<!DOCTYPE html>
<!-- saved from url=(0054)https://xie.infoq.cn/article/9e57819677d77f9a34852f6e9 -->
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<!-- <geektime>1591721999994</geektime> -->
    
    
        <title>NIO 看破也说破（五）： 搞，今天就搞，搞懂Buffer_Java_小眼睛聊技术_InfoQ写作社区</title>
        <meta name="description" content="前言Java NIO 中的三件法宝：Channel、Selector和Buffer。前面几节中，我们花了很大篇幅讲过Selector，咱们今天只搞Buffer。希望能通过本文搞明白Buffer的基本用" id="metadesc">
    
    <meta name="keywords" content="Buffer,NIO,Selector,看破,说破,搞懂,Java,法宝,Channel,很大,篇幅,希望,明白,用法,原理" id="metakeywords">
    <meta property="og:image" content="https://static001.infoq.cn/static/write/img/write-favicon.jpg">

    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">
    
        <link rel="icon" type="image/png" sizes="32x32" href="https://static001.infoq.cn/static/write/img/write-favicon.jpg">
        <link rel="icon" type="image/png" sizes="16x16" href="https://static001.infoq.cn/static/write/img/write-favicon.jpg">
    
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="format-detection" content="telephone=no">
    <meta name="applicable-device" content="pc,mobile">
    <meta http-equiv="Cache-Control" content="no-transform">
    <meta http-equiv="Cache-Control" content="no-siteapp">
    <link rel="canonical" href="https://xie.infoq.cn/article/9e57819677d77f9a34852f6e9">
    <meta property="og:title" content="NIO 看破也说破（五）： 搞，今天就搞，搞懂Buffer_Java_小眼睛聊技术_InfoQ写作社区">
    <meta property="og:url" content="https://xie.infoq.cn/article/9e57819677d77f9a34852f6e9">
    <meta property="og:description" content="前言Java NIO 中的三件法宝：Channel、Selector和Buffer。前面几节中，我们花了很大篇幅讲过Selector，咱们今天只搞Buffer。希望能通过本文搞明白Buffer的基本用">

    <script type="text/javascript" async="" src="./NIO 看破也说破（五）Buffer_Java_InfoQ_files/js"></script><script type="text/javascript" async="" src="./NIO 看破也说破（五）Buffer_Java_InfoQ_files/js(1)"></script><script async="" src="./NIO 看破也说破（五）Buffer_Java_InfoQ_files/sensorsdata.min.js.下载" charset="UTF-8"></script><script src="./NIO 看破也说破（五）Buffer_Java_InfoQ_files/hm.js.下载"></script><script src="./NIO 看破也说破（五）Buffer_Java_InfoQ_files/hm(1).js.下载"></script><script async="" src="./NIO 看破也说破（五）Buffer_Java_InfoQ_files/analytics.js.下载"></script><script src="./NIO 看破也说破（五）Buffer_Java_InfoQ_files/push.js.下载"></script><script type="text/javascript" src="./NIO 看破也说破（五）Buffer_Java_InfoQ_files/jweixin-1.4.0.js.下载"></script>
    <script type="text/javascript" src="./NIO 看破也说破（五）Buffer_Java_InfoQ_files/bufferLogger.1.0.8.min.js.下载"></script>
    <script src="./NIO 看破也说破（五）Buffer_Java_InfoQ_files/dingtalk.open.js.下载"></script>
    
        <script type="text/javascript" src="./NIO 看破也说破（五）Buffer_Java_InfoQ_files/aliplayer-min.js.下载"></script>
        <script type="text/javascript" src="./NIO 看破也说破（五）Buffer_Java_InfoQ_files/hls.8361666e7e2690d988ff5fe775b62bbe.js.下载"></script>
    
        
    <script src="./NIO 看破也说破（五）Buffer_Java_InfoQ_files/jquery-1.12.4.min(1).js.下载"></script>
    
    <script src="./NIO 看破也说破（五）Buffer_Java_InfoQ_files/mantis.min.js.下载"></script>
    <script type="text/javascript">
        if (!('flex' in document.documentElement.style) && !navigator.userAgent.match(/spider|googlebot|bingbot|geekbang|yahoo! Slurp/i)) {
            window.location.href = '//static001.geekbang.org/static/common/browser_update/index.html'
        }
    </script>
    <script>
        (function(){
            var bp = document.createElement('script');
            var curProtocol = window.location.protocol.split(':')[0];
            if (curProtocol === 'https'){
                bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
            }
            else{
                bp.src = 'http://push.zhanzhang.baidu.com/push.js';
            }
            var s = document.getElementsByTagName("script")[0];
            s.parentNode.insertBefore(bp, s);
        })();
    </script>
<link href="./NIO 看破也说破（五）Buffer_Java_InfoQ_files/app.f787f7a6.css" rel="stylesheet"><script src="./NIO 看破也说破（五）Buffer_Java_InfoQ_files/1725952827-mantis_probe.min.js.下载" type="text/javascript" defer=""></script><meta name="referrer" content="no-referrer-when-downgrade"><script charset="utf-8" src="./NIO 看破也说破（五）Buffer_Java_InfoQ_files/chunk-codemirror.5b03effd.js.下载"></script><link rel="stylesheet" type="text/css" href="./NIO 看破也说破（五）Buffer_Java_InfoQ_files/chunk-katex.ce0dccd9.css"><script charset="utf-8" src="./NIO 看破也说破（五）Buffer_Java_InfoQ_files/chunk-katex.7cd46588.js.下载"></script><link rel="stylesheet" type="text/css" href="./NIO 看破也说破（五）Buffer_Java_InfoQ_files/chunk-geek-editor.b88154cf.css"><script charset="utf-8" src="./NIO 看破也说破（五）Buffer_Java_InfoQ_files/chunk-geek-editor.9ca1b5f5.js.下载"></script><link rel="stylesheet" type="text/css" href="./NIO 看破也说破（五）Buffer_Java_InfoQ_files/chunk-12b29e91.053549ea.css"><script charset="utf-8" src="./NIO 看破也说破（五）Buffer_Java_InfoQ_files/chunk-12b29e91.1598f130.js.下载"></script><link rel="stylesheet" type="text/css" href="./NIO 看破也说破（五）Buffer_Java_InfoQ_files/PageArticle.76a73b25.css"><script charset="utf-8" src="./NIO 看破也说破（五）Buffer_Java_InfoQ_files/PageArticle.9509fe6c.js.下载"></script></head>

<body>
<div data-v-b110a92e="" data-v-4a1c10f0="" id="layout" layout="" class="page-article-layout ready skin-base size-base" style="padding-bottom: 0px;"><div data-v-b110a92e="" layout-header-wrap="" class="layout-header-wrap"><div data-v-2c781bfe="" data-v-b110a92e="" class="common-header-pc"><div data-v-2c781bfe="" class="shim"></div><div data-v-2c781bfe="" class="header"><div data-v-2c781bfe="" class="wrap"><div data-v-2c781bfe="" class="layout-content header-content"><div data-v-2c781bfe="" class="logo"><a data-v-2c781bfe="" href="https://www.infoq.cn/" class="main-logo"><img data-v-2c781bfe="" src="./NIO 看破也说破（五）Buffer_Java_InfoQ_files/logo.b51e49df.png" alt="logo"></a><a data-v-2c781bfe="" href="https://xie.infoq.cn/" class="sub-logo"><img data-v-2c781bfe="" src="" alt="logo"></a></div><div data-v-2c781bfe="" class="header-middle"><div data-v-2c781bfe="" class="nav"><ul data-v-2c781bfe=""><li data-v-2c781bfe=""><a data-v-2c781bfe="" href="https://xie.infoq.cn/" class="">首页</a></li><li data-v-2c781bfe=""><!----><a data-v-2c781bfe="" href="https://xie.infoq.cn/square/13" target="_blank" rel="" class=""> 玩转社区 </a></li><li data-v-2c781bfe=""><!----><a data-v-2c781bfe="" href="https://xie.infoq.cn/tag/3" target="_blank" rel="" class=""> Java </a></li><li data-v-2c781bfe=""><!----><a data-v-2c781bfe="" href="https://xie.infoq.cn/tag/211" target="_blank" rel="" class=""> 开源 </a></li><li data-v-2c781bfe=""><!----><a data-v-2c781bfe="" href="https://xie.infoq.cn/tag/238" target="_blank" rel="" class=""> 架构 </a></li><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----></ul><div data-v-2c781bfe="" class="more"> 全部标签 <i data-v-2c781bfe="" class="iconfont"></i></div></div><div data-v-2c781bfe="" class="search-container"><div data-v-2c781bfe="" class="search-wrap"><input data-v-2c781bfe="" type="text" placeholder="搜索" class="search-input"><span data-v-2c781bfe="" class="search-btn iconfont"></span></div></div><!----><div data-v-2c781bfe="" class="write-btn-warp"><div data-v-2c781bfe="" gk-button="" gkbtn-color="green" gkbtn-size="small" class="write-btn Button_button_3onsJ"> 写点什么 </div><div data-v-2c781bfe="" class="scene" style="display: none;"><h4 data-v-2c781bfe=""><i data-v-2c781bfe="" class="iconfont"></i>创作场景</h4><div data-v-2c781bfe="" class="close"><i data-v-2c781bfe="" class="iconfont"></i></div><ul data-v-2c781bfe=""><li data-v-2c781bfe="">记录自己日常工作的实践、心得</li><li data-v-2c781bfe="">发表对生活和职场的感悟</li><li data-v-2c781bfe="">针对感兴趣的事件发表随笔或者杂谈</li><li data-v-2c781bfe="">从0到1详细介绍你掌握的一门语言、一个技术，或者一个兴趣、爱好</li><li data-v-2c781bfe="">或者，就直接把你的个人博客、公众号直接搬到这里</li></ul></div></div></div><div data-v-2c781bfe="" class="account"><span data-v-2c781bfe="" class="route">登录</span><span data-v-2c781bfe="" class="line"></span><span data-v-2c781bfe="" class="route">注册</span></div></div></div><div data-v-2c781bfe="" class="more-tags"><div data-v-2c781bfe="" class="inner-content"><div data-v-4300d745="" data-v-2c781bfe="" class="com-label-list"><a data-v-4426e0e8="" data-v-4300d745="" href="https://xie.infoq.cn/tag/9434" com-label-title="" class="com-label-title">OpenHarmony</a><a data-v-4426e0e8="" data-v-4300d745="" href="https://xie.infoq.cn/tag/303" com-label-title="" class="com-label-title">算法</a><a data-v-4426e0e8="" data-v-4300d745="" href="https://xie.infoq.cn/tag/14135" com-label-title="" class="com-label-title">元宇宙</a><a data-v-4426e0e8="" data-v-4300d745="" href="https://xie.infoq.cn/tag/84" com-label-title="" class="com-label-title">MySQL</a><a data-v-4426e0e8="" data-v-4300d745="" href="https://xie.infoq.cn/tag/5237" com-label-title="" class="com-label-title">移动开发</a><a data-v-4426e0e8="" data-v-4300d745="" href="https://xie.infoq.cn/tag/221" com-label-title="" class="com-label-title">学习方法</a><a data-v-4426e0e8="" data-v-4300d745="" href="https://xie.infoq.cn/tag/221" com-label-title="" class="com-label-title">学习方法</a><a data-v-4426e0e8="" data-v-4300d745="" href="https://xie.infoq.cn/tag/17178" com-label-title="" class="com-label-title">Web3.0</a><a data-v-4426e0e8="" data-v-4300d745="" href="https://xie.infoq.cn/tag/203" com-label-title="" class="com-label-title">高效工作</a><a data-v-4426e0e8="" data-v-4300d745="" href="https://xie.infoq.cn/tag/92" com-label-title="" class="com-label-title">数据库</a><a data-v-4426e0e8="" data-v-4300d745="" href="https://xie.infoq.cn/tag/8" com-label-title="" class="com-label-title">Python</a><a data-v-4426e0e8="" data-v-4300d745="" href="https://xie.infoq.cn/tag/661" com-label-title="" class="com-label-title">音视频</a><a data-v-4426e0e8="" data-v-4300d745="" href="https://xie.infoq.cn/tag/371" com-label-title="" class="com-label-title">前端</a><a data-v-4426e0e8="" data-v-4300d745="" href="https://xie.infoq.cn/tag/242" com-label-title="" class="com-label-title">AI</a><a data-v-4426e0e8="" data-v-4300d745="" href="https://xie.infoq.cn/tag/143" com-label-title="" class="com-label-title">大数据</a><a data-v-4426e0e8="" data-v-4300d745="" href="https://xie.infoq.cn/tag/204" com-label-title="" class="com-label-title">团队管理</a><a data-v-4426e0e8="" data-v-4300d745="" href="https://xie.infoq.cn/tag/232" com-label-title="" class="com-label-title">程序员</a><a data-v-4426e0e8="" data-v-4300d745="" href="https://xie.infoq.cn/tag/317" com-label-title="" class="com-label-title">运维</a><a data-v-4426e0e8="" data-v-4300d745="" href="https://xie.infoq.cn/tag/200" com-label-title="" class="com-label-title">深度思考</a><a data-v-4426e0e8="" data-v-4300d745="" href="https://xie.infoq.cn/tag/1081" com-label-title="" class="com-label-title">低代码</a><a data-v-4426e0e8="" data-v-4300d745="" href="https://xie.infoq.cn/tag/97" com-label-title="" class="com-label-title">redis</a><a data-v-4426e0e8="" data-v-4300d745="" href="https://xie.infoq.cn/tag/19" com-label-title="" class="com-label-title">golang</a><a data-v-4426e0e8="" data-v-4300d745="" href="https://xie.infoq.cn/tag/294" com-label-title="" class="com-label-title">微服务架构</a><a data-v-4426e0e8="" data-v-4300d745="" href="https://xie.infoq.cn/tag/21" com-label-title="" class="com-label-title">flutter</a><a data-v-2c781bfe="" data-v-4300d745="" href="https://xie.infoq.cn/tag" target="_blank" class="more-tag com-label-title"> 查看更多 <i data-v-2c781bfe="" data-v-4300d745="" class="iconfont"></i></a></div></div></div></div></div></div><div data-v-b110a92e="" inner-content="" class="inner-content"><!----><!----><!----><div data-v-4a1c10f0="" data-v-b110a92e="" class="layout-content article-content"><div data-v-4a1c10f0="" class="article-fixed-wrap" data-v-b110a92e="" style="width: 150px;"><div data-v-4a1c10f0="" class="side-operation" style="top: 91px;"><div data-v-4a51d84b="" data-v-4a1c10f0="" class="widget-operation side" wxshareurl="https://xie.infoq.cn/article/9e57819677d77f9a34852f6e9" authorinfo="[object Object]"><div data-v-4a51d84b="" class="toggle-menu btn"><i data-v-4a51d84b="" class="iconfont"></i></div><div data-v-4a51d84b="" class="like btn"><i data-v-4a51d84b="" class="iconfont"></i><i data-v-4a51d84b="" class="like-num">6</i></div><div data-v-4a51d84b="" class="favorite btn"><i data-v-4a51d84b="" class="iconfont"></i></div><div data-v-4a51d84b="" class="comment btn"><i data-v-4a51d84b="" class="iconfont"></i></div><div data-v-4a51d84b="" class="weixin btn"><span data-v-4a51d84b="" class="gkui-popup share-popup-left share-popup"><i data-v-4a51d84b="" class="iconfont"></i><!----></span></div><div data-v-4a51d84b="" class="weibo btn"><i data-v-4a51d84b="" class="iconfont"></i></div><div data-v-4a51d84b="" class="horde btn"><i data-v-4a51d84b="" class="iconfont"></i></div><!----><!----></div></div></div><div data-v-4a1c10f0="" data-v-b110a92e="" class="main"><!----><!----><h1 data-v-4a1c10f0="" data-v-b110a92e="" class="article-title">NIO 看破也说破（五）： 搞，今天就搞，搞懂 Buffer</h1><div data-v-4a1c10f0="" data-v-b110a92e="" class="author-information"><div data-v-4a1c10f0="" data-v-b110a92e="" class="row"><div data-v-4a1c10f0="" data-v-b110a92e="" class="author-name"> 作者：<span data-v-3bc80670="" data-v-6281d13f="" data-v-4a1c10f0="" class="ctn" data-v-b110a92e=""><a data-v-3bc80670="" rel="nofollow" com-author-name="" class="com-author-name">小眼睛聊技术</a><!----></span></div></div><div data-v-4a1c10f0="" data-v-b110a92e="" class="row article-head"><ul data-v-4a1c10f0="" data-v-b110a92e="" class="read-time"><li data-v-4a1c10f0="" data-v-b110a92e="">2020-06-04  <!----></li><li data-v-4a1c10f0="" data-v-b110a92e=""><p data-v-4a1c10f0="" data-v-b110a92e="" class="time-style">本文字数：3674 字 </p><!----><p data-v-4a1c10f0="" data-v-b110a92e="" class="time-style">阅读完需：约 12 分钟</p></li></ul></div></div><div data-v-4a1c10f0="" data-v-b110a92e="" class="article-cover"><img data-v-4a1c10f0="" data-v-b110a92e="" src="./NIO 看破也说破（五）Buffer_Java_InfoQ_files/77816aef280df70b5a583a8abd46f007.jpeg" alt="NIO 看破也说破（五）： 搞，今天就搞，搞懂Buffer"></div><div data-v-4a1c10f0="" data-v-b110a92e="" class="article-detaile"><div data-v-fbbc0218="" data-v-4a1c10f0="" class="article-preview-content size-base" data-v-b110a92e=""><div data-v-fbbc0218="" data-type="doc" class="article-preview"><div contenteditable="false" translate="no" class="ProseMirror"><h1 data-id="heading0" data-type="heading" top="247">前言</h1><p data-type="paragraph"><br class="ProseMirror-trailingBreak"></p><p data-type="paragraph">Java NIO 中的三件法宝：<code data-type="codeinline">Channel</code> 、<code data-type="codeinline">Selector</code> 和 <code data-type="codeinline">Buffer</code> 。前面几节中，我们花了很大篇幅讲过 <code data-type="codeinline">Selector</code> ，咱们今天只搞 <code data-type="codeinline">Buffer</code> 。希望能通过本文搞明白 <code data-type="codeinline">Buffer</code> 的基本用法和原理。</p><p data-type="paragraph"><br class="ProseMirror-trailingBreak"></p><p data-type="paragraph">掌握重点：</p><ol data-type="numberedlist"><li><p data-number="1" data-type="paragraph">两个重要指针不停变换</p></li><li><p data-number="2" data-type="paragraph">一块 <code data-type="codeinline">Buffer</code> 可读可写</p></li><li><p data-number="3" data-type="paragraph">基本操作的 api 用法</p></li><li><p data-number="4" data-type="paragraph"><code data-type="codeinline">ByteBuffer</code> 可以在 JVM 堆外分配直接内存</p></li></ol><h1 data-id="heading1" data-type="heading" top="601.4000244140625">基本操作</h1><p data-type="paragraph"><br class="ProseMirror-trailingBreak"></p><p data-type="paragraph">上一篇我们模拟 client 发送请求的时候代码如下：</p><div data-type="codeblock"><div data-codeblock-wrap=""><div data-codeblock-codes=""><div class="simplebar" data-simplebar="init"><div class="simplebar-wrapper" style="margin: 0px;"><div class="simplebar-height-auto-observer-wrapper"><div class="simplebar-height-auto-observer"></div></div> <div class="simplebar-mask"><div class="simplebar-offset" style="right: 0px; bottom: 0px;"><div class="simplebar-content-wrapper" style="height: auto; overflow: scroll;"><div class="simplebar-content" style="padding: 0px;"><div><pre data-origin="pm_code_preview" lang="java"><code data-type="codeline"><span data-type="markclass" class="hljs-type">InputStream</span> <span data-type="markclass" class="hljs-variable">inputStream</span> <span data-type="markclass" class="hljs-operator">=</span> socket.getInputStream();</code><code data-type="codeline"><span data-type="markclass" class="hljs-type">BufferedReader</span> <span data-type="markclass" class="hljs-variable">br</span> <span data-type="markclass" class="hljs-operator">=</span> <span data-type="markclass" class="hljs-keyword">new</span> <span data-type="markclass" class="hljs-title class_">BufferedReader</span>(<span data-type="markclass" class="hljs-keyword">new</span> <span data-type="markclass" class="hljs-title class_">InputStreamReader</span>(inputStream));</code><code data-type="codeline">System.out.printf(<span data-type="markclass" class="hljs-string">"接到服务端响应：%s，处理了%d\r\n"</span>, br.readLine(), (System.currentTimeMillis() - start));</code><code data-type="codeline">br.close();</code><code data-type="codeline">inputStream.close();</code></pre></div></div></div></div></div> <div class="simplebar-placeholder" style="width: 770px; height: 110px;"></div></div> <div class="simplebar-track simplebar-horizontal" style="visibility: visible;"><div class="simplebar-scrollbar simplebar-visible" style="width: 740px; display: block; transform: translate3d(0px, 0px, 0px);"></div></div> <div class="simplebar-track simplebar-vertical" style="visibility: visible;"><div class="simplebar-scrollbar simplebar-visible" style="height: 0px; display: none;"></div></div></div></div> <div data-codeblock-copy="">复制代码</div> <div data-codeblock-index=""><div data-codeblock-number="1"></div><div data-codeblock-number="2"></div><div data-codeblock-number="3"></div><div data-codeblock-number="4"></div><div data-codeblock-number="5"></div></div></div></div><p data-type="paragraph">在普通 BIO 模式下，我们只能自己维护一个 byte 数组或者是 char 数组来进行批量读写，或者使用 <code data-type="codeinline">BufferedReader</code> 和 <code data-type="codeinline">BufferedInputStream</code> 来做读写缓冲区。</p><div data-type="codeblock"><div data-codeblock-wrap=""><div data-codeblock-codes=""><div class="simplebar" data-simplebar="init"><div class="simplebar-wrapper" style="margin: 0px;"><div class="simplebar-height-auto-observer-wrapper"><div class="simplebar-height-auto-observer"></div></div> <div class="simplebar-mask"><div class="simplebar-offset" style="right: 0px; bottom: 0px;"><div class="simplebar-content-wrapper" style="height: auto; overflow: hidden scroll;"><div class="simplebar-content" style="padding: 0px;"><div><pre data-origin="pm_code_preview" lang="java"><code data-type="codeline">buffer.clear();</code><code data-type="codeline">buffer.put((<span data-type="markclass" class="hljs-string">"收到，你发来的是："</span> + sb + <span data-type="markclass" class="hljs-string">"\r\n"</span>).getBytes(<span data-type="markclass" class="hljs-string">"utf-8"</span>));</code><code data-type="codeline">buffer.flip();</code></pre></div></div></div></div></div> <div class="simplebar-placeholder" style="width: 770px; height: 70px;"></div></div> <div class="simplebar-track simplebar-horizontal" style="visibility: hidden;"><div class="simplebar-scrollbar simplebar-visible" style="width: 0px; display: none;"></div></div> <div class="simplebar-track simplebar-vertical" style="visibility: visible;"><div class="simplebar-scrollbar simplebar-visible" style="height: 0px; display: none;"></div></div></div></div> <div data-codeblock-copy="">复制代码</div> <div data-codeblock-index=""><div data-codeblock-number="1"></div><div data-codeblock-number="2"></div><div data-codeblock-number="3"></div></div></div></div><p data-type="paragraph">Java NIO Buffer 用于和 NIO Channel 交互，我们从<code data-type="codeinline">Channel</code> 中读取数据到 <code data-type="codeinline">Buffer</code> 里，从 <code data-type="codeinline">Buffer</code> 把数据写入到 <code data-type="codeinline">Channel</code>。本质上，<span data-name="red" style="color: #F5222D" data-type="color"><strong data-type="strong">就是存在一块内存区，可以用来写入数据，并在稍后读取出来。这块内存被 NIO Buffer 包裹起来，对外提供一系列的读写方便开发的接口</strong></span>。</p><ul data-type="bulletedlist"><li><p data-type="paragraph">把数据写入 <code data-type="codeinline">Buffer</code>；</p></li><li><p data-type="paragraph">调用 flip()；</p></li><li><p data-type="paragraph">从 <code data-type="codeinline">Buffer</code> 中读取数据；</p></li><li><p data-type="paragraph">调用 clear() 或者 compact()</p></li></ul><p data-type="paragraph">当写入数据到 <code data-type="codeinline">Buffer</code> 中时，<code data-type="codeinline">Buffer</code> 会记录已经写入的数据大小。当需要读数据时，通过 flip() 方法把 <code data-type="codeinline">Buffer</code> 从写模式调整为读模式；在读模式下，可以读取所有已经写入的数据。</p><h1 data-id="heading2" data-type="heading" top="1383.800048828125">Buffer 实现</h1><p data-type="paragraph"><br class="ProseMirror-trailingBreak"></p><p data-type="paragraph">缓存区，内部使用字节数组存储数据，并维护几个特殊变量，实现数据的反复利用。在 java.nio.Buffer 中定义了 4 个成员变量：</p><ol data-type="numberedlist"><li><p data-number="1" data-type="paragraph"><strong data-type="strong">mark</strong>：初始值为 -1，用于备份当前的 position ;</p></li><li><p data-number="2" data-type="paragraph"><strong data-type="strong">position</strong>：初始值为 0，position 表示当前可以写入或读取数据的位置，当写入或读取一个数据后，position 向前移动到下一个位置；</p></li><li><p data-number="3" data-type="paragraph"><strong data-type="strong">limit</strong>：写模式下，limit 表示最多能往 Buffer 里写多少数据，等于 capacity 值；读模式下，limit 表示最多可以读取多少数据。</p></li><li><p data-number="4" data-type="paragraph"><strong data-type="strong">capacity</strong>：缓存数组大小</p></li></ol><p data-type="paragraph"><br class="ProseMirror-trailingBreak"></p><p data-type="paragraph">核心点：<strong data-type="strong">对于 Buffer 的操作，就是在不停的变换 position 和 limit 指针的位置，达到定位读取位置和终止位置的目的，从而可以准确的在边界内读取数据。</strong></p><p data-type="paragraph"><br class="ProseMirror-trailingBreak"></p><p data-type="paragraph">代码实现：</p><div data-type="codeblock"><div data-codeblock-wrap=""><div data-codeblock-codes=""><div class="simplebar" data-simplebar="init"><div class="simplebar-wrapper" style="margin: 0px;"><div class="simplebar-height-auto-observer-wrapper"><div class="simplebar-height-auto-observer"></div></div> <div class="simplebar-mask"><div class="simplebar-offset" style="right: 0px; bottom: 0px;"><div class="simplebar-content-wrapper" style="height: auto; overflow: hidden scroll;"><div class="simplebar-content" style="padding: 0px;"><div><pre data-origin="pm_code_preview" lang="java"><code data-type="codeline"><span data-type="markclass" class="hljs-comment">// Invariants: mark &lt;= position &lt;= limit &lt;= capacity</span></code><code data-type="codeline"><span data-type="markclass" class="hljs-keyword">private</span> <span data-type="markclass" class="hljs-type">int</span> <span data-type="markclass" class="hljs-variable">mark</span> <span data-type="markclass" class="hljs-operator">=</span> -<span data-type="markclass" class="hljs-number">1</span>;</code><code data-type="codeline"><span data-type="markclass" class="hljs-keyword">private</span> <span data-type="markclass" class="hljs-type">int</span> <span data-type="markclass" class="hljs-variable">position</span> <span data-type="markclass" class="hljs-operator">=</span> <span data-type="markclass" class="hljs-number">0</span>;</code><code data-type="codeline"><span data-type="markclass" class="hljs-keyword">private</span> <span data-type="markclass" class="hljs-type">int</span> limit;</code><code data-type="codeline"><span data-type="markclass" class="hljs-keyword">private</span> <span data-type="markclass" class="hljs-type">int</span> capacity;</code></pre></div></div></div></div></div> <div class="simplebar-placeholder" style="width: 770px; height: 110px;"></div></div> <div class="simplebar-track simplebar-horizontal" style="visibility: hidden;"><div class="simplebar-scrollbar simplebar-visible" style="width: 0px; display: none;"></div></div> <div class="simplebar-track simplebar-vertical" style="visibility: visible;"><div class="simplebar-scrollbar simplebar-visible" style="height: 0px; display: none;"></div></div></div></div> <div data-codeblock-copy="">复制代码</div> <div data-codeblock-index=""><div data-codeblock-number="1"></div><div data-codeblock-number="2"></div><div data-codeblock-number="3"></div><div data-codeblock-number="4"></div><div data-codeblock-number="5"></div></div></div></div><p data-type="paragraph">以字节缓冲区为例，<code data-type="codeinline">ByteBuffer</code> 是一个抽象类，不能直接通过 new 语句来创建，只能通过一个 static 方法 allocate 来创建：</p><div data-type="codeblock"><div data-codeblock-wrap=""><div data-codeblock-codes=""><div class="simplebar" data-simplebar="init"><div class="simplebar-wrapper" style="margin: 0px;"><div class="simplebar-height-auto-observer-wrapper"><div class="simplebar-height-auto-observer"></div></div> <div class="simplebar-mask"><div class="simplebar-offset" style="right: 0px; bottom: 0px;"><div class="simplebar-content-wrapper" style="height: auto; overflow: hidden scroll;"><div class="simplebar-content" style="padding: 0px;"><div><pre data-origin="pm_code_preview" lang="java"><code data-type="codeline"><span data-type="markclass" class="hljs-type">ByteBuffer</span> <span data-type="markclass" class="hljs-variable">byteBuffer</span> <span data-type="markclass" class="hljs-operator">=</span> ByteBuffer.allocate(<span data-type="markclass" class="hljs-number">10</span>);</code></pre></div></div></div></div></div> <div class="simplebar-placeholder" style="width: 770px; height: 30px;"></div></div> <div class="simplebar-track simplebar-horizontal" style="visibility: hidden;"><div class="simplebar-scrollbar simplebar-visible" style="width: 0px; display: none;"></div></div> <div class="simplebar-track simplebar-vertical" style="visibility: visible;"><div class="simplebar-scrollbar simplebar-visible" style="height: 0px; display: none;"></div></div></div></div> <div data-codeblock-copy="">复制代码</div> <div data-codeblock-index=""><div data-codeblock-number="1"></div></div></div></div><p data-type="paragraph">调用上述语句，相当于创建一个大小为 10 个字节的 <code data-type="codeinline">ByteBuffer</code> ，此时 mark = -1, position = 0, limit = 10, capacity = 10</p><p data-type="paragraph"><br class="ProseMirror-trailingBreak"></p><p data-type="paragraph">我们看一下 <code data-type="codeinline">Buffer</code> 的常见方法，内部是如何实现的：</p><h2 data-id="heading3" data-type="heading" top="2329.800048828125">put</h2><p data-type="paragraph"><br class="ProseMirror-trailingBreak"></p><p data-type="paragraph">put 方法是把一个 byte 变量 x 放到缓冲区中，同时 position 会加 1</p><div data-type="codeblock"><div data-codeblock-wrap=""><div data-codeblock-codes=""><div class="simplebar" data-simplebar="init"><div class="simplebar-wrapper" style="margin: 0px;"><div class="simplebar-height-auto-observer-wrapper"><div class="simplebar-height-auto-observer"></div></div> <div class="simplebar-mask"><div class="simplebar-offset" style="right: 0px; bottom: 0px;"><div class="simplebar-content-wrapper" style="height: auto; overflow: hidden scroll;"><div class="simplebar-content" style="padding: 0px;"><div><pre data-origin="pm_code_preview" lang="java"><code data-type="codeline"><span data-type="markclass" class="hljs-keyword">public</span> ByteBuffer <span data-type="markclass" class="hljs-title function_">put</span><span data-type="markclass" class="hljs-params">(<span data-type="markclass" class="hljs-type">byte</span> x)</span> {</code><code data-type="codeline">    hb[ix(nextPutIndex())] = x;</code><code data-type="codeline">    <span data-type="markclass" class="hljs-keyword">return</span> <span data-type="markclass" class="hljs-built_in">this</span>;</code><code data-type="codeline">}</code><code data-type="codeline"><br class="ProseMirror-trailingBreak"></code><code data-type="codeline"><span data-type="markclass" class="hljs-keyword">final</span> <span data-type="markclass" class="hljs-type">int</span> <span data-type="markclass" class="hljs-title function_">nextPutIndex</span><span data-type="markclass" class="hljs-params">()</span> {                          <span data-type="markclass" class="hljs-comment">// package-private</span></code><code data-type="codeline">    <span data-type="markclass" class="hljs-keyword">if</span> (position &gt;= limit)</code><code data-type="codeline">        <span data-type="markclass" class="hljs-keyword">throw</span> <span data-type="markclass" class="hljs-keyword">new</span> <span data-type="markclass" class="hljs-title class_">BufferOverflowException</span>();</code><code data-type="codeline">    <span data-type="markclass" class="hljs-keyword">return</span> position++;</code><code data-type="codeline">}</code></pre></div></div></div></div></div> <div class="simplebar-placeholder" style="width: 770px; height: 210px;"></div></div> <div class="simplebar-track simplebar-horizontal" style="visibility: hidden;"><div class="simplebar-scrollbar simplebar-visible" style="width: 0px; display: none;"></div></div> <div class="simplebar-track simplebar-vertical" style="visibility: visible;"><div class="simplebar-scrollbar simplebar-visible" style="height: 0px; display: none;"></div></div></div></div> <div data-codeblock-copy="">复制代码</div> <div data-codeblock-index=""><div data-codeblock-number="1"></div><div data-codeblock-number="2"></div><div data-codeblock-number="3"></div><div data-codeblock-number="4"></div><div data-codeblock-number="5"></div><div data-codeblock-number="6"></div><div data-codeblock-number="7"></div><div data-codeblock-number="8"></div><div data-codeblock-number="9"></div><div data-codeblock-number="10"></div></div></div></div><p data-type="paragraph"><br class="ProseMirror-trailingBreak"></p><div data-type="image"><div data-content="" data-style-width="100%" data-style-bordertype="boxShadow"><img src="./NIO 看破也说破（五）Buffer_Java_InfoQ_files/5121dded4733c41a2d8c4af750f56787.gif"> <!----></div></div><p data-type="paragraph"><br class="ProseMirror-trailingBreak"></p><p data-type="paragraph">一起看一下不停 put 数据时，几个变量的变化：</p><div data-type="codeblock"><div data-codeblock-wrap=""><div data-codeblock-codes=""><div class="simplebar" data-simplebar="init"><div class="simplebar-wrapper" style="margin: 0px;"><div class="simplebar-height-auto-observer-wrapper"><div class="simplebar-height-auto-observer"></div></div> <div class="simplebar-mask"><div class="simplebar-offset" style="right: 0px; bottom: 0px;"><div class="simplebar-content-wrapper" style="height: auto; overflow: hidden scroll;"><div class="simplebar-content" style="padding: 0px;"><div><pre data-origin="pm_code_preview" lang="java"><code data-type="codeline"><span data-type="markclass" class="hljs-type">ByteBuffer</span> <span data-type="markclass" class="hljs-variable">byteBuffer</span> <span data-type="markclass" class="hljs-operator">=</span> ByteBuffer.allocate(<span data-type="markclass" class="hljs-number">10</span>);</code><code data-type="codeline">byteBuffer.put((<span data-type="markclass" class="hljs-type">byte</span>) <span data-type="markclass" class="hljs-string">'l'</span>);</code><code data-type="codeline">byteBuffer.put((<span data-type="markclass" class="hljs-type">byte</span>) <span data-type="markclass" class="hljs-string">'o'</span>);</code><code data-type="codeline">byteBuffer.put((<span data-type="markclass" class="hljs-type">byte</span>) <span data-type="markclass" class="hljs-string">'v'</span>);</code><code data-type="codeline">byteBuffer.put((<span data-type="markclass" class="hljs-type">byte</span>) <span data-type="markclass" class="hljs-string">'e'</span>);</code><code data-type="codeline">System.out.println(byteBuffer.limit()); <span data-type="markclass" class="hljs-comment">// 结果10</span></code><code data-type="codeline">System.out.println(byteBuffer.position());<span data-type="markclass" class="hljs-comment">// 结果4</span></code><code data-type="codeline">System.out.println(byteBuffer.capacity());<span data-type="markclass" class="hljs-comment">// 结果10</span></code><code data-type="codeline">byteBuffer.put((<span data-type="markclass" class="hljs-type">byte</span>) <span data-type="markclass" class="hljs-string">' '</span>);</code><code data-type="codeline">byteBuffer.put((<span data-type="markclass" class="hljs-type">byte</span>) <span data-type="markclass" class="hljs-string">'x'</span>);</code><code data-type="codeline">byteBuffer.put((<span data-type="markclass" class="hljs-type">byte</span>) <span data-type="markclass" class="hljs-string">'y'</span>);</code><code data-type="codeline">byteBuffer.put((<span data-type="markclass" class="hljs-type">byte</span>) <span data-type="markclass" class="hljs-string">'j'</span>);</code><code data-type="codeline">System.out.println(byteBuffer.limit());<span data-type="markclass" class="hljs-comment">// 结果10</span></code><code data-type="codeline">System.out.println(byteBuffer.position());<span data-type="markclass" class="hljs-comment">// 结果8</span></code><code data-type="codeline">System.out.println(byteBuffer.capacity());<span data-type="markclass" class="hljs-comment">// 结果10</span></code></pre></div></div></div></div></div> <div class="simplebar-placeholder" style="width: 770px; height: 310px;"></div></div> <div class="simplebar-track simplebar-horizontal" style="visibility: hidden;"><div class="simplebar-scrollbar simplebar-visible" style="width: 0px; display: none;"></div></div> <div class="simplebar-track simplebar-vertical" style="visibility: visible;"><div class="simplebar-scrollbar simplebar-visible" style="height: 0px; display: none;"></div></div></div></div> <div data-codeblock-copy="">复制代码</div> <div data-codeblock-index=""><div data-codeblock-number="1"></div><div data-codeblock-number="2"></div><div data-codeblock-number="3"></div><div data-codeblock-number="4"></div><div data-codeblock-number="5"></div><div data-codeblock-number="6"></div><div data-codeblock-number="7"></div><div data-codeblock-number="8"></div><div data-codeblock-number="9"></div><div data-codeblock-number="10"></div><div data-codeblock-number="11"></div><div data-codeblock-number="12"></div><div data-codeblock-number="13"></div><div data-codeblock-number="14"></div><div data-codeblock-number="15"></div></div></div></div><p data-type="paragraph"><br class="ProseMirror-trailingBreak"></p><h2 data-id="heading4" data-type="heading" top="3276">get</h2><p data-type="paragraph"><br class="ProseMirror-trailingBreak"></p><p data-type="paragraph">get 方法，是从 position 的位置去取缓冲区中的一个字节</p><div data-type="codeblock"><div data-codeblock-wrap=""><div data-codeblock-codes=""><div class="simplebar" data-simplebar="init"><div class="simplebar-wrapper" style="margin: 0px;"><div class="simplebar-height-auto-observer-wrapper"><div class="simplebar-height-auto-observer"></div></div> <div class="simplebar-mask"><div class="simplebar-offset" style="right: 0px; bottom: 0px;"><div class="simplebar-content-wrapper" style="height: auto; overflow: hidden scroll;"><div class="simplebar-content" style="padding: 0px;"><div><pre data-origin="pm_code_preview" lang="java"><code data-type="codeline"><span data-type="markclass" class="hljs-keyword">public</span> <span data-type="markclass" class="hljs-type">byte</span> <span data-type="markclass" class="hljs-title function_">get</span><span data-type="markclass" class="hljs-params">()</span> {</code><code data-type="codeline">    <span data-type="markclass" class="hljs-keyword">return</span> hb[ix(nextGetIndex())];</code><code data-type="codeline">}</code><code data-type="codeline"><br class="ProseMirror-trailingBreak"></code><code data-type="codeline"><span data-type="markclass" class="hljs-keyword">final</span> <span data-type="markclass" class="hljs-type">int</span> <span data-type="markclass" class="hljs-title function_">nextGetIndex</span><span data-type="markclass" class="hljs-params">()</span> {                          <span data-type="markclass" class="hljs-comment">// package-private</span></code><code data-type="codeline">    <span data-type="markclass" class="hljs-keyword">if</span> (position &gt;= limit)</code><code data-type="codeline">        <span data-type="markclass" class="hljs-keyword">throw</span> <span data-type="markclass" class="hljs-keyword">new</span> <span data-type="markclass" class="hljs-title class_">BufferUnderflowException</span>();</code><code data-type="codeline">    <span data-type="markclass" class="hljs-keyword">return</span> position++;</code><code data-type="codeline">}</code></pre></div></div></div></div></div> <div class="simplebar-placeholder" style="width: 770px; height: 190px;"></div></div> <div class="simplebar-track simplebar-horizontal" style="visibility: hidden;"><div class="simplebar-scrollbar simplebar-visible" style="width: 0px; display: none;"></div></div> <div class="simplebar-track simplebar-vertical" style="visibility: visible;"><div class="simplebar-scrollbar simplebar-visible" style="height: 0px; display: none;"></div></div></div></div> <div data-codeblock-copy="">复制代码</div> <div data-codeblock-index=""><div data-codeblock-number="1"></div><div data-codeblock-number="2"></div><div data-codeblock-number="3"></div><div data-codeblock-number="4"></div><div data-codeblock-number="5"></div><div data-codeblock-number="6"></div><div data-codeblock-number="7"></div><div data-codeblock-number="8"></div><div data-codeblock-number="9"></div></div></div></div><p data-type="paragraph"><br class="ProseMirror-trailingBreak"></p><h2 data-id="heading5" data-type="heading" top="3691.60009765625">flip</h2><p data-type="paragraph"><br class="ProseMirror-trailingBreak"></p><p data-type="paragraph">如果想在一个 <code data-type="codeinline">Buffer</code> 中放入了数据，然后想从中读取的话，就要把 position 调到我想读的那个位置才行，同时需要调整 limit。</p><div data-type="codeblock"><div data-codeblock-wrap=""><div data-codeblock-codes=""><div class="simplebar" data-simplebar="init"><div class="simplebar-wrapper" style="margin: 0px;"><div class="simplebar-height-auto-observer-wrapper"><div class="simplebar-height-auto-observer"></div></div> <div class="simplebar-mask"><div class="simplebar-offset" style="right: 0px; bottom: 0px;"><div class="simplebar-content-wrapper" style="height: auto; overflow: hidden scroll;"><div class="simplebar-content" style="padding: 0px;"><div><pre data-origin="pm_code_preview" lang="java"><code data-type="codeline">byteBuffer.limit(byteBuffer.position())</code><code data-type="codeline">byteBuffer.position(<span data-type="markclass" class="hljs-number">0</span>);</code></pre></div></div></div></div></div> <div class="simplebar-placeholder" style="width: 770px; height: 50px;"></div></div> <div class="simplebar-track simplebar-horizontal" style="visibility: hidden;"><div class="simplebar-scrollbar simplebar-visible" style="width: 0px; display: none;"></div></div> <div class="simplebar-track simplebar-vertical" style="visibility: visible;"><div class="simplebar-scrollbar simplebar-visible" style="height: 0px; display: none;"></div></div></div></div> <div data-codeblock-copy="">复制代码</div> <div data-codeblock-index=""><div data-codeblock-number="1"></div><div data-codeblock-number="2"></div></div></div></div><p data-type="paragraph"><br class="ProseMirror-trailingBreak"></p><div data-type="image"><div data-content="" data-style-width="100%" data-style-bordertype="boxShadow"><img src="./NIO 看破也说破（五）Buffer_Java_InfoQ_files/986fa14fc391c1f7a2ae4db4f6734b9f.jpeg"> <!----></div></div><p data-type="paragraph"><br class="ProseMirror-trailingBreak"></p><p data-type="paragraph">Java 中把这两步操作，封装在一个 flip 方法中：</p><div data-type="codeblock"><div data-codeblock-wrap=""><div data-codeblock-codes=""><div class="simplebar" data-simplebar="init"><div class="simplebar-wrapper" style="margin: 0px;"><div class="simplebar-height-auto-observer-wrapper"><div class="simplebar-height-auto-observer"></div></div> <div class="simplebar-mask"><div class="simplebar-offset" style="right: 0px; bottom: 0px;"><div class="simplebar-content-wrapper" style="height: auto; overflow: hidden scroll;"><div class="simplebar-content" style="padding: 0px;"><div><pre data-origin="pm_code_preview" lang="java"><code data-type="codeline"><span data-type="markclass" class="hljs-keyword">public</span> <span data-type="markclass" class="hljs-keyword">final</span> Buffer <span data-type="markclass" class="hljs-title function_">flip</span><span data-type="markclass" class="hljs-params">()</span> {</code><code data-type="codeline">    limit = position;</code><code data-type="codeline">    position = <span data-type="markclass" class="hljs-number">0</span>;</code><code data-type="codeline">    mark = -<span data-type="markclass" class="hljs-number">1</span>;</code><code data-type="codeline">    <span data-type="markclass" class="hljs-keyword">return</span> <span data-type="markclass" class="hljs-built_in">this</span>;</code><code data-type="codeline">}</code></pre></div></div></div></div></div> <div class="simplebar-placeholder" style="width: 770px; height: 130px;"></div></div> <div class="simplebar-track simplebar-horizontal" style="visibility: hidden;"><div class="simplebar-scrollbar simplebar-visible" style="width: 0px; display: none;"></div></div> <div class="simplebar-track simplebar-vertical" style="visibility: visible;"><div class="simplebar-scrollbar simplebar-visible" style="height: 0px; display: none;"></div></div></div></div> <div data-codeblock-copy="">复制代码</div> <div data-codeblock-index=""><div data-codeblock-number="1"></div><div data-codeblock-number="2"></div><div data-codeblock-number="3"></div><div data-codeblock-number="4"></div><div data-codeblock-number="5"></div><div data-codeblock-number="6"></div></div></div></div><p data-type="paragraph"><br class="ProseMirror-trailingBreak"></p><div data-type="image"><div data-content="" data-style-width="100%" data-style-bordertype="boxShadow"><img src="./NIO 看破也说破（五）Buffer_Java_InfoQ_files/ab0f3fecf5d2980dffd14cc1d828fae2.gif"> <!----></div></div><h2 data-id="heading6" data-type="heading" top="4378.39990234375">mark</h2><p data-type="paragraph"><br class="ProseMirror-trailingBreak"></p><p data-type="paragraph">mark 就很容易理解了，它就是记住当前的位置用的</p><div data-type="codeblock"><div data-codeblock-wrap=""><div data-codeblock-codes=""><div class="simplebar" data-simplebar="init"><div class="simplebar-wrapper" style="margin: 0px;"><div class="simplebar-height-auto-observer-wrapper"><div class="simplebar-height-auto-observer"></div></div> <div class="simplebar-mask"><div class="simplebar-offset" style="right: 0px; bottom: 0px;"><div class="simplebar-content-wrapper" style="height: auto; overflow: hidden scroll;"><div class="simplebar-content" style="padding: 0px;"><div><pre data-origin="pm_code_preview" lang="java"><code data-type="codeline"><span data-type="markclass" class="hljs-keyword">public</span> <span data-type="markclass" class="hljs-keyword">final</span> Buffer <span data-type="markclass" class="hljs-title function_">mark</span><span data-type="markclass" class="hljs-params">()</span> {</code><code data-type="codeline">    mark = position;</code><code data-type="codeline">    <span data-type="markclass" class="hljs-keyword">return</span> <span data-type="markclass" class="hljs-built_in">this</span>;</code><code data-type="codeline">}</code></pre></div></div></div></div></div> <div class="simplebar-placeholder" style="width: 770px; height: 90px;"></div></div> <div class="simplebar-track simplebar-horizontal" style="visibility: hidden;"><div class="simplebar-scrollbar simplebar-visible" style="width: 0px; display: none;"></div></div> <div class="simplebar-track simplebar-vertical" style="visibility: visible;"><div class="simplebar-scrollbar simplebar-visible" style="height: 0px; display: none;"></div></div></div></div> <div data-codeblock-copy="">复制代码</div> <div data-codeblock-index=""><div data-codeblock-number="1"></div><div data-codeblock-number="2"></div><div data-codeblock-number="3"></div><div data-codeblock-number="4"></div></div></div></div><p data-type="paragraph">在调用过 mark 以后，再进行缓冲区的读写操作，position 就会发生变化，为了再回到当初的位置，我们可以调用 reset 方法恢复 position 的值：</p><div data-type="codeblock"><div data-codeblock-wrap=""><div data-codeblock-codes=""><div class="simplebar" data-simplebar="init"><div class="simplebar-wrapper" style="margin: 0px;"><div class="simplebar-height-auto-observer-wrapper"><div class="simplebar-height-auto-observer"></div></div> <div class="simplebar-mask"><div class="simplebar-offset" style="right: 0px; bottom: 0px;"><div class="simplebar-content-wrapper" style="height: auto; overflow: hidden scroll;"><div class="simplebar-content" style="padding: 0px;"><div><pre data-origin="pm_code_preview" lang="java"><code data-type="codeline"><span data-type="markclass" class="hljs-keyword">public</span> <span data-type="markclass" class="hljs-keyword">final</span> Buffer <span data-type="markclass" class="hljs-title function_">reset</span><span data-type="markclass" class="hljs-params">()</span> {</code><code data-type="codeline">    <span data-type="markclass" class="hljs-type">int</span> <span data-type="markclass" class="hljs-variable">m</span> <span data-type="markclass" class="hljs-operator">=</span> mark;</code><code data-type="codeline">    <span data-type="markclass" class="hljs-keyword">if</span> (m &lt; <span data-type="markclass" class="hljs-number">0</span>)</code><code data-type="codeline">        <span data-type="markclass" class="hljs-keyword">throw</span> <span data-type="markclass" class="hljs-keyword">new</span> <span data-type="markclass" class="hljs-title class_">InvalidMarkException</span>();</code><code data-type="codeline">    position = m;</code><code data-type="codeline">    <span data-type="markclass" class="hljs-keyword">return</span> <span data-type="markclass" class="hljs-built_in">this</span>;</code><code data-type="codeline">}</code></pre></div></div></div></div></div> <div class="simplebar-placeholder" style="width: 770px; height: 150px;"></div></div> <div class="simplebar-track simplebar-horizontal" style="visibility: hidden;"><div class="simplebar-scrollbar simplebar-visible" style="width: 0px; display: none;"></div></div> <div class="simplebar-track simplebar-vertical" style="visibility: visible;"><div class="simplebar-scrollbar simplebar-visible" style="height: 0px; display: none;"></div></div></div></div> <div data-codeblock-copy="">复制代码</div> <div data-codeblock-index=""><div data-codeblock-number="1"></div><div data-codeblock-number="2"></div><div data-codeblock-number="3"></div><div data-codeblock-number="4"></div><div data-codeblock-number="5"></div><div data-codeblock-number="6"></div><div data-codeblock-number="7"></div></div></div></div><h2 data-id="heading7" data-type="heading" top="4935.60009765625">clear</h2><p data-type="paragraph"><br class="ProseMirror-trailingBreak"></p><p data-type="paragraph">把 <code data-type="codeinline">Buffer</code> 中特殊的 4 个变量初始为原始值</p><div data-type="codeblock"><div data-codeblock-wrap=""><div data-codeblock-codes=""><div class="simplebar" data-simplebar="init"><div class="simplebar-wrapper" style="margin: 0px;"><div class="simplebar-height-auto-observer-wrapper"><div class="simplebar-height-auto-observer"></div></div> <div class="simplebar-mask"><div class="simplebar-offset" style="right: 0px; bottom: 0px;"><div class="simplebar-content-wrapper" style="height: auto; overflow: hidden scroll;"><div class="simplebar-content" style="padding: 0px;"><div><pre data-origin="pm_code_preview" lang="java"><code data-type="codeline"><span data-type="markclass" class="hljs-keyword">public</span> <span data-type="markclass" class="hljs-keyword">final</span> Buffer <span data-type="markclass" class="hljs-title function_">clear</span><span data-type="markclass" class="hljs-params">()</span> {</code><code data-type="codeline">    position = <span data-type="markclass" class="hljs-number">0</span>;</code><code data-type="codeline">    limit = capacity;</code><code data-type="codeline">    mark = -<span data-type="markclass" class="hljs-number">1</span>;</code><code data-type="codeline">    <span data-type="markclass" class="hljs-keyword">return</span> <span data-type="markclass" class="hljs-built_in">this</span>;</code><code data-type="codeline">}</code></pre></div></div></div></div></div> <div class="simplebar-placeholder" style="width: 770px; height: 130px;"></div></div> <div class="simplebar-track simplebar-horizontal" style="visibility: hidden;"><div class="simplebar-scrollbar simplebar-visible" style="width: 0px; display: none;"></div></div> <div class="simplebar-track simplebar-vertical" style="visibility: visible;"><div class="simplebar-scrollbar simplebar-visible" style="height: 0px; display: none;"></div></div></div></div> <div data-codeblock-copy="">复制代码</div> <div data-codeblock-index=""><div data-codeblock-number="1"></div><div data-codeblock-number="2"></div><div data-codeblock-number="3"></div><div data-codeblock-number="4"></div><div data-codeblock-number="5"></div><div data-codeblock-number="6"></div></div></div></div><p data-type="paragraph"><br class="ProseMirror-trailingBreak"></p><p data-type="paragraph">回顾一下核心点：<strong data-type="strong">对于 Buffer 的操作，就是在不停的变换 position 和 limit 指针的位置，达到定位读取位置和终止位置的目的，从而可以准确的在边界内读取数据。</strong></p><h1 data-id="heading8" data-type="heading" top="5352.80029296875">Direct Buffer</h1><p data-type="paragraph"><br class="ProseMirror-trailingBreak"></p><p data-type="paragraph">在创建 <code data-type="codeinline">ByteBuffer</code> 是我们是采用的静态方法直接 allocate 得到一个 buffer 对象：</p><div data-type="codeblock"><div data-codeblock-wrap=""><div data-codeblock-codes=""><div class="simplebar" data-simplebar="init"><div class="simplebar-wrapper" style="margin: 0px;"><div class="simplebar-height-auto-observer-wrapper"><div class="simplebar-height-auto-observer"></div></div> <div class="simplebar-mask"><div class="simplebar-offset" style="right: 0px; bottom: 0px;"><div class="simplebar-content-wrapper" style="height: auto; overflow: hidden scroll;"><div class="simplebar-content" style="padding: 0px;"><div><pre data-origin="pm_code_preview" lang="java"><code data-type="codeline"><span data-type="markclass" class="hljs-type">ByteBuffer</span> <span data-type="markclass" class="hljs-variable">buf</span> <span data-type="markclass" class="hljs-operator">=</span> ByteBuffer.allocate(<span data-type="markclass" class="hljs-number">1024</span>);</code></pre></div></div></div></div></div> <div class="simplebar-placeholder" style="width: 770px; height: 30px;"></div></div> <div class="simplebar-track simplebar-horizontal" style="visibility: hidden;"><div class="simplebar-scrollbar simplebar-visible" style="width: 0px; display: none;"></div></div> <div class="simplebar-track simplebar-vertical" style="visibility: visible;"><div class="simplebar-scrollbar simplebar-visible" style="height: 0px; display: none;"></div></div></div></div> <div data-codeblock-copy="">复制代码</div> <div data-codeblock-index=""><div data-codeblock-number="1"></div></div></div></div><p data-type="paragraph">在 JVM 中，创建的对象是放入在堆中。比如，当我们 <code data-type="codeinline">Object o = new Object()</code> 时，会在堆内存上分配一块内存空间给 <code data-type="codeinline">new Object()</code> ，在栈空间上持有引用 <code data-type="codeinline">o</code> 保存 <code data-type="codeinline">Object</code> 的内存地址 。JVM 做垃圾回收，会把堆中的对象，在不同的分区中来回拷贝。内存地址会频繁发生变化，本身 <code data-type="codeinline">Buffer</code> 会频繁读写，这样会导致内存整理繁琐。有没有办法脱离 JVM 对象管理呢？在创建 <code data-type="codeinline">Buffer</code> 的静态方法中还有一个方法：</p><div data-type="codeblock"><div data-codeblock-wrap=""><div data-codeblock-codes=""><div class="simplebar" data-simplebar="init"><div class="simplebar-wrapper" style="margin: 0px;"><div class="simplebar-height-auto-observer-wrapper"><div class="simplebar-height-auto-observer"></div></div> <div class="simplebar-mask"><div class="simplebar-offset" style="right: 0px; bottom: 0px;"><div class="simplebar-content-wrapper" style="height: auto; overflow: hidden scroll;"><div class="simplebar-content" style="padding: 0px;"><div><pre data-origin="pm_code_preview" lang="java"><code data-type="codeline"><span data-type="markclass" class="hljs-type">ByteBuffer</span> <span data-type="markclass" class="hljs-variable">buf</span> <span data-type="markclass" class="hljs-operator">=</span> ByteBuffer.allocateDirect(<span data-type="markclass" class="hljs-number">1024</span>);</code></pre></div></div></div></div></div> <div class="simplebar-placeholder" style="width: 770px; height: 30px;"></div></div> <div class="simplebar-track simplebar-horizontal" style="visibility: hidden;"><div class="simplebar-scrollbar simplebar-visible" style="width: 0px; display: none;"></div></div> <div class="simplebar-track simplebar-vertical" style="visibility: visible;"><div class="simplebar-scrollbar simplebar-visible" style="height: 0px; display: none;"></div></div></div></div> <div data-codeblock-copy="">复制代码</div> <div data-codeblock-index=""><div data-codeblock-number="1"></div></div></div></div><p data-type="paragraph">我们来比对一下方法的实现：</p><div data-type="codeblock"><div data-codeblock-wrap=""><div data-codeblock-codes=""><div class="simplebar" data-simplebar="init"><div class="simplebar-wrapper" style="margin: 0px;"><div class="simplebar-height-auto-observer-wrapper"><div class="simplebar-height-auto-observer"></div></div> <div class="simplebar-mask"><div class="simplebar-offset" style="right: 0px; bottom: 0px;"><div class="simplebar-content-wrapper" style="height: auto; overflow: hidden scroll;"><div class="simplebar-content" style="padding: 0px;"><div><pre data-origin="pm_code_preview" lang="java"><code data-type="codeline"><span data-type="markclass" class="hljs-keyword">public</span> <span data-type="markclass" class="hljs-keyword">static</span> ByteBuffer <span data-type="markclass" class="hljs-title function_">allocateDirect</span><span data-type="markclass" class="hljs-params">(<span data-type="markclass" class="hljs-type">int</span> capacity)</span> {</code><code data-type="codeline">    <span data-type="markclass" class="hljs-keyword">return</span> <span data-type="markclass" class="hljs-keyword">new</span> <span data-type="markclass" class="hljs-title class_">DirectByteBuffer</span>(capacity);</code><code data-type="codeline">}</code><code data-type="codeline"><br class="ProseMirror-trailingBreak"></code><code data-type="codeline"><span data-type="markclass" class="hljs-keyword">public</span> <span data-type="markclass" class="hljs-keyword">static</span> ByteBuffer <span data-type="markclass" class="hljs-title function_">allocate</span><span data-type="markclass" class="hljs-params">(<span data-type="markclass" class="hljs-type">int</span> capacity)</span> {</code><code data-type="codeline">    <span data-type="markclass" class="hljs-keyword">if</span> (capacity &lt; <span data-type="markclass" class="hljs-number">0</span>)</code><code data-type="codeline">        <span data-type="markclass" class="hljs-keyword">throw</span> <span data-type="markclass" class="hljs-keyword">new</span> <span data-type="markclass" class="hljs-title class_">IllegalArgumentException</span>();</code><code data-type="codeline">    <span data-type="markclass" class="hljs-keyword">return</span> <span data-type="markclass" class="hljs-keyword">new</span> <span data-type="markclass" class="hljs-title class_">HeapByteBuffer</span>(capacity, capacity);</code><code data-type="codeline">}</code></pre></div></div></div></div></div> <div class="simplebar-placeholder" style="width: 770px; height: 190px;"></div></div> <div class="simplebar-track simplebar-horizontal" style="visibility: hidden;"><div class="simplebar-scrollbar simplebar-visible" style="width: 0px; display: none;"></div></div> <div class="simplebar-track simplebar-vertical" style="visibility: visible;"><div class="simplebar-scrollbar simplebar-visible" style="height: 0px; display: none;"></div></div></div></div> <div data-codeblock-copy="">复制代码</div> <div data-codeblock-index=""><div data-codeblock-number="1"></div><div data-codeblock-number="2"></div><div data-codeblock-number="3"></div><div data-codeblock-number="4"></div><div data-codeblock-number="5"></div><div data-codeblock-number="6"></div><div data-codeblock-number="7"></div><div data-codeblock-number="8"></div><div data-codeblock-number="9"></div></div></div></div><p data-type="paragraph">调用 allocate() 创建了一个 <code data-type="codeinline">HeapByteBuffer</code> ，调用 allocateDirect() 创建的是 <code data-type="codeinline">DirectByteBuffer</code> 。看名字很直观的表达，一个是「堆」内存，一个是「直接」内存。</p><p data-type="paragraph"><br class="ProseMirror-trailingBreak"></p><p data-type="paragraph">看一下 <code data-type="codeinline">DirectByteBuffer</code> 的实现：</p><div data-type="codeblock"><div data-codeblock-wrap=""><div data-codeblock-codes=""><div class="simplebar" data-simplebar="init"><div class="simplebar-wrapper" style="margin: 0px;"><div class="simplebar-height-auto-observer-wrapper"><div class="simplebar-height-auto-observer"></div></div> <div class="simplebar-mask"><div class="simplebar-offset" style="right: 0px; bottom: 0px;"><div class="simplebar-content-wrapper" style="height: auto; overflow: hidden scroll;"><div class="simplebar-content" style="padding: 0px;"><div><pre data-origin="pm_code_preview" lang="java"><code data-type="codeline"><span data-type="markclass" class="hljs-comment">// Primary constructor</span></code><code data-type="codeline">    <span data-type="markclass" class="hljs-comment">//</span></code><code data-type="codeline">DirectByteBuffer(<span data-type="markclass" class="hljs-type">int</span> cap) {                   <span data-type="markclass" class="hljs-comment">// package-private</span></code><code data-type="codeline"><br class="ProseMirror-trailingBreak"></code><code data-type="codeline">    <span data-type="markclass" class="hljs-built_in">super</span>(-<span data-type="markclass" class="hljs-number">1</span>, <span data-type="markclass" class="hljs-number">0</span>, cap, cap);</code><code data-type="codeline">    <span data-type="markclass" class="hljs-type">boolean</span> <span data-type="markclass" class="hljs-variable">pa</span> <span data-type="markclass" class="hljs-operator">=</span> VM.isDirectMemoryPageAligned();</code><code data-type="codeline">    <span data-type="markclass" class="hljs-type">int</span> <span data-type="markclass" class="hljs-variable">ps</span> <span data-type="markclass" class="hljs-operator">=</span> Bits.pageSize();</code><code data-type="codeline">    <span data-type="markclass" class="hljs-type">long</span> <span data-type="markclass" class="hljs-variable">size</span> <span data-type="markclass" class="hljs-operator">=</span> Math.max(<span data-type="markclass" class="hljs-number">1L</span>, (<span data-type="markclass" class="hljs-type">long</span>)cap + (pa ? ps : <span data-type="markclass" class="hljs-number">0</span>));</code><code data-type="codeline">    Bits.reserveMemory(size, cap);</code><code data-type="codeline"><br class="ProseMirror-trailingBreak"></code><code data-type="codeline">    <span data-type="markclass" class="hljs-type">long</span> <span data-type="markclass" class="hljs-variable">base</span> <span data-type="markclass" class="hljs-operator">=</span> <span data-type="markclass" class="hljs-number">0</span>;</code><code data-type="codeline">    <span data-type="markclass" class="hljs-keyword">try</span> {</code><code data-type="codeline">        base = unsafe.allocateMemory(size);</code><code data-type="codeline">    } <span data-type="markclass" class="hljs-keyword">catch</span> (OutOfMemoryError x) {</code><code data-type="codeline">        Bits.unreserveMemory(size, cap);</code><code data-type="codeline">        <span data-type="markclass" class="hljs-keyword">throw</span> x;</code><code data-type="codeline">    }</code><code data-type="codeline">    unsafe.setMemory(base, size, (<span data-type="markclass" class="hljs-type">byte</span>) <span data-type="markclass" class="hljs-number">0</span>);</code><code data-type="codeline">    <span data-type="markclass" class="hljs-keyword">if</span> (pa &amp;&amp; (base % ps != <span data-type="markclass" class="hljs-number">0</span>)) {</code><code data-type="codeline">        <span data-type="markclass" class="hljs-comment">// Round up to page boundary</span></code><code data-type="codeline">        address = base + ps - (base &amp; (ps - <span data-type="markclass" class="hljs-number">1</span>));</code><code data-type="codeline">    } <span data-type="markclass" class="hljs-keyword">else</span> {</code><code data-type="codeline">        address = base;</code><code data-type="codeline">    }</code><code data-type="codeline">    cleaner = Cleaner.create(<span data-type="markclass" class="hljs-built_in">this</span>, <span data-type="markclass" class="hljs-keyword">new</span> <span data-type="markclass" class="hljs-title class_">Deallocator</span>(base, size, cap));</code><code data-type="codeline">    att = <span data-type="markclass" class="hljs-literal">null</span>;</code><code data-type="codeline">}</code></pre></div></div></div></div></div> <div class="simplebar-placeholder" style="width: 770px; height: 550px;"></div></div> <div class="simplebar-track simplebar-horizontal" style="visibility: hidden;"><div class="simplebar-scrollbar simplebar-visible" style="width: 0px; display: none;"></div></div> <div class="simplebar-track simplebar-vertical" style="visibility: visible;"><div class="simplebar-scrollbar simplebar-visible" style="height: 0px; display: none;"></div></div></div></div> <div data-codeblock-copy="">复制代码</div> <div data-codeblock-index=""><div data-codeblock-number="1"></div><div data-codeblock-number="2"></div><div data-codeblock-number="3"></div><div data-codeblock-number="4"></div><div data-codeblock-number="5"></div><div data-codeblock-number="6"></div><div data-codeblock-number="7"></div><div data-codeblock-number="8"></div><div data-codeblock-number="9"></div><div data-codeblock-number="10"></div><div data-codeblock-number="11"></div><div data-codeblock-number="12"></div><div data-codeblock-number="13"></div><div data-codeblock-number="14"></div><div data-codeblock-number="15"></div><div data-codeblock-number="16"></div><div data-codeblock-number="17"></div><div data-codeblock-number="18"></div><div data-codeblock-number="19"></div><div data-codeblock-number="20"></div><div data-codeblock-number="21"></div><div data-codeblock-number="22"></div><div data-codeblock-number="23"></div><div data-codeblock-number="24"></div><div data-codeblock-number="25"></div><div data-codeblock-number="26"></div><div data-codeblock-number="27"></div></div></div></div><p data-type="paragraph"><br class="ProseMirror-trailingBreak"></p><p data-type="paragraph">这里最重要的就是使用了 unsafe.allocateMemory 来分配内存，而 allocateMemory 是一个 native 方法，会调用 malloc 方法在 JVM 外分配一块内存空间。</p><p data-type="paragraph"><br class="ProseMirror-trailingBreak"></p><p data-type="paragraph">总之，这里在 Java 堆外申请了一块内存，并把这个内存的地址记录下来。以后要是再使用这个<code data-type="codeinline">ByteBuffer</code>的话，就会直接访问从 address 开始的那一段内存。</p><p data-type="paragraph"><br class="ProseMirror-trailingBreak"></p><p data-type="paragraph"><code data-type="codeinline">DirectBuffer</code> 一个直观的优点是不被 GC 管理，所以发生 GC 的时候，整理内存的压力就会小。当然，它并不是完全不被 GC 管理还是能被回收的，但是在 GC 平常整理内存的时候确实是不会去管它。</p><p data-type="paragraph"><br class="ProseMirror-trailingBreak"></p><h1 data-id="heading9" data-type="heading" top="7121.60009765625">类结构</h1><p data-type="paragraph"><br class="ProseMirror-trailingBreak"></p><p data-type="paragraph">我们只是以常见的 <code data-type="codeinline">ByteBuffer</code> 为例，在 NIO 中还提供了各种类型的 Buffer ，这里就不再赘述。</p><div data-type="image"><div data-content="" data-style-width="100%" data-style-bordertype="boxShadow"><img src="./NIO 看破也说破（五）Buffer_Java_InfoQ_files/ad2487fe8cde8d33ad70e6aeb8dcf0be.jpeg"> <div data-title="">图片源于网络</div></div></div><h1 data-id="heading10" data-type="heading" top="7348.2001953125">结论</h1><p data-type="paragraph"><br class="ProseMirror-trailingBreak"></p><ol data-type="numberedlist"><li><p data-number="1" data-type="paragraph"><code data-type="codeinline"><span data-name="red" style="color: #F5222D" data-type="color">Buffer</span></code><span data-name="red" style="color: #F5222D" data-type="color"> 中有两个重要指针 position 和 limit 不停变换位置</span></p></li><li><p data-number="2" data-type="paragraph"><span data-name="red" style="color: #F5222D" data-type="color">一块 <code data-type="codeinline"><span data-name="red" style="color: #F5222D" data-type="color">Buffer</span></code> 可读可写，内部是一个 capacity 大小的数组</span></p></li><li><p data-number="3" data-type="paragraph"><span data-name="red" style="color: #F5222D" data-type="color">基本操作的 api 用法，put 、get、flip、mark、clear</span></p></li><li><p data-number="4" data-type="paragraph"><span data-name="red" style="color: #F5222D" data-type="color">flip 方法改变了指针 position 和 limit 的位置</span></p></li><li><p data-number="5" data-type="paragraph"><span data-name="red" style="color: #F5222D" data-type="color">可以在 JVM 堆外分配直接内存</span></p></li></ol><p data-type="paragraph"><br class="ProseMirror-trailingBreak"></p><p data-type="paragraph">今天就搞到的这里，划的重点需要牢记，<code data-type="codeinline">Buffer</code> 的操作不注意顺序会出现各种问题。</p><p data-type="paragraph"><br class="ProseMirror-trailingBreak"></p><h2 data-id="heading11" data-type="heading" top="7701">系列</h2><p data-type="paragraph"><a href="https://xie.infoq.cn/article/0e36ad9712c8d9ad8f7a7c570" title="" data-type="link">NIO 看破也说破（一）—— Linux/IO 基础</a><br class="ProseMirror-trailingBreak"></p><p data-type="paragraph"><a href="https://xie.infoq.cn/article/e8ab7c9020253b83355c10661" title="" data-type="link">NIO 看破也说破（二）—— Java 中的两种 BIO</a><br class="ProseMirror-trailingBreak"></p><p data-type="paragraph"><a href="https://xie.infoq.cn/article/1f44643161e1666b6a30b85e7" title="" data-type="link">NIO 看破也说破（三）—— 不同的 IO 模型</a><br class="ProseMirror-trailingBreak"></p><p data-type="paragraph"><a href="https://xie.infoq.cn/article/b9baa25c9d506e4a1cb459fe0" title="" data-type="link">NIO 看破也说破（四）—— Java 的 NIO</a><br class="ProseMirror-trailingBreak"></p><p data-type="paragraph"><a href="https://xie.infoq.cn/article/9e57819677d77f9a34852f6e9" title="" data-type="link">NIO 看破也说破（五）： 搞，今天就搞，搞懂Buffer</a><br class="ProseMirror-trailingBreak"></p><p data-type="paragraph"><br class="ProseMirror-trailingBreak"></p><h1 data-id="heading12" data-type="heading" top="7955">关注我</h1><p data-type="paragraph">如果您在微信阅读，请您点击链接 <a href="https://xie.infoq.cn/link?target=https%3A%2F%2Fmp.weixin.qq.com%2Fmp%2Fprofile_ext%3Faction%3Dhome%26__biz%3DMzI3MDYwOTYwOA%3D%3D%26scene%3D110%23wechat_redirect" title="" data-type="link">关注我</a> ，如果您在 PC 上阅读请扫码关注我，欢迎与我交流随时指出错误</p><div data-type="image"><div data-content="" data-style-width="25%" data-style-bordertype="boxShadow"><img src="./NIO 看破也说破（五）Buffer_Java_InfoQ_files/3874eef202c2e5d161059dcf58e1430f.png"> <!----></div></div><p data-type="paragraph"><br class="ProseMirror-trailingBreak"></p></div></div><div data-v-759cadff="" data-v-fbbc0218="" class="selection-operation-bar note-bar popup-note-menu down"><div data-v-759cadff="" class="arrow down"></div><div data-v-759cadff="" class="main"><div data-v-759cadff="" class="menu line"><i data-v-a949bb52="" data-v-759cadff="" class="com-icon iconfont icon-hover" style="font-size: 20px; color: rgb(255, 255, 255);"></i><span data-v-759cadff="" class="text">划线</span></div><!----><div data-v-759cadff="" class="menu comment"><i data-v-a949bb52="" data-v-759cadff="" class="com-icon iconfont icon-hover" style="font-size: 20px; color: rgb(255, 255, 255);"></i><span data-v-759cadff="" class="text">评论</span></div><div data-v-759cadff="" class="menu copy"><i data-v-a949bb52="" data-v-759cadff="" class="com-icon iconfont icon-hover" style="font-size: 20px; color: rgb(255, 255, 255);"></i><span data-v-759cadff="" class="text">复制</span></div></div></div></div></div><div data-v-4a1c10f0="" data-v-b110a92e="" class="author-information after-content"><div data-v-4a1c10f0="" data-v-b110a92e="" class="row"><span data-v-4a1c10f0="" data-v-b110a92e="" class="date">发布于: 2020-06-04</span><span data-v-4a1c10f0="" data-v-b110a92e="" class="views">阅读数: 2294</span></div></div><div data-v-4a1c10f0="" data-v-b110a92e="" class="copyright"><p data-v-4a1c10f0="" data-v-b110a92e="">版权声明: 本文为 InfoQ 作者【小眼睛聊技术】的原创文章。</p><p data-v-4a1c10f0="" data-v-b110a92e="">原文链接:【<a href="https://xie.infoq.cn/article/9e57819677d77f9a34852f6e9" target="_blank">https://xie.infoq.cn/article/9e57819677d77f9a34852f6e9</a>】。文章转载请联系作者。</p></div><!----><div data-v-4300d745="" data-v-4a1c10f0="" class="com-label-list tag-list" data-v-b110a92e=""><a data-v-4426e0e8="" data-v-4300d745="" href="https://xie.infoq.cn/tag/3" com-label-title="" class="com-label-title">Java</a><a data-v-4426e0e8="" data-v-4300d745="" href="https://xie.infoq.cn/tag/189" com-label-title="" class="com-label-title">学习</a><a data-v-4426e0e8="" data-v-4300d745="" href="https://xie.infoq.cn/tag/201" com-label-title="" class="com-label-title">读书笔记</a><a data-v-4426e0e8="" data-v-4300d745="" href="https://xie.infoq.cn/tag/238" com-label-title="" class="com-label-title">架构</a><a data-v-4426e0e8="" data-v-4300d745="" href="https://xie.infoq.cn/tag/531" com-label-title="" class="com-label-title">后端</a></div><div data-v-affe19d2="" data-v-4a1c10f0="" author-card="" class="com-author-card author-info" data-v-b110a92e=""><div data-v-affe19d2="" class="author-card"><div data-v-affe19d2="" class="top"><div data-v-affe19d2="" class="avatar"><div data-v-7b3025e7="" data-v-affe19d2="" class="com-avatar-wrap"><img data-v-7b3025e7="" src="./NIO 看破也说破（五）Buffer_Java_InfoQ_files/449a9571.jpg" alt="用户头像" class="com-avatar" style="width: 55px; height: 55px;"><!----></div></div><div data-v-affe19d2="" class="info"><div data-v-affe19d2="" class="top"><h3 data-v-affe19d2="" class="author-name"><span data-v-3bc80670="" data-v-6281d13f="" data-v-affe19d2="" class="ctn"><a data-v-3bc80670="" rel="nofollow" com-author-name="" class="com-author-name">小眼睛聊技术</a><!----></span></h3><div data-v-d2847db8="" data-v-affe19d2="" gk-button="" gkbtn-color="unfollow" gkbtn-size="small" class="geek-foll-btn Button_button_3onsJ" follow-button="" data-follow="0"><i data-v-affe19d2="" class="iconfont"></i>关注</div></div><p data-v-affe19d2="" class="mood"> 欢迎关注公众号“小眼睛聊技术” <span data-v-affe19d2="" class="dot"></span> 2018-11-12 加入</p></div></div><!----><p data-v-affe19d2="" class="intro">互联网老兵，关注产品、技术、管理</p></div></div><div data-v-4a51d84b="" data-v-4a1c10f0="" class="widget-operation-bottom widget-operation inner" info="[object Object]" wxshareurl="https://xie.infoq.cn/article/9e57819677d77f9a34852f6e9" data-v-b110a92e=""><!----><div data-v-4a51d84b="" class="like btn"><i data-v-4a51d84b="" class="iconfont"></i><!----></div><div data-v-4a51d84b="" class="favorite btn"><i data-v-4a51d84b="" class="iconfont"></i></div><!----><div data-v-4a51d84b="" class="weixin btn"><span data-v-4a51d84b="" class="gkui-popup share-popup-top share-popup"><i data-v-4a51d84b="" class="iconfont"></i><!----></span></div><div data-v-4a51d84b="" class="weibo btn"><i data-v-4a51d84b="" class="iconfont"></i></div><div data-v-4a51d84b="" class="horde btn"><i data-v-4a51d84b="" class="iconfont"></i></div><div data-v-4a51d84b="" data-self="2" data-label="举报" class="extra btn"><i data-v-4a51d84b="" class="iconfont"></i></div><!----></div><!----><div data-v-b7e0eae6="" data-v-4a1c10f0="" class="article-comment-block comment-list-wrap" data-v-b110a92e=""><div data-v-b7e0eae6="" class="comment-list"><h2 data-v-b7e0eae6="">评论 <span data-v-b7e0eae6="" class="comment-number">(5 条评论)</span></h2><div data-v-b7e0eae6="" class="comment-form"><div data-v-b7e0eae6="" class="comment-input no-reference"><div data-v-045f148c="" data-v-b7e0eae6="" contenteditable="plaintext-only" spellcheck="false" placeholder="写下你的想法，一起交流" class="textarea comment-textarea empty"></div> <!----></div><div data-v-b7e0eae6="" class="comment-operation"><div data-v-b7e0eae6="" gk-button="" gkbtn-color="green" gkbtn-size="normal" disabled="disabled" class="comment-btn Button_button_3onsJ"> 发布 </div></div></div><div data-v-b7e0eae6="" class="list"><!----><div data-v-fcafb8d2="" data-v-54bade26="" data-v-b7e0eae6="" class="reply-item comment-item"><div data-v-54bade26="" data-v-fcafb8d2="" class="comment-avatar"><div data-v-7b3025e7="" data-v-54bade26="" class="com-avatar-wrap" data-v-fcafb8d2=""><img data-v-7b3025e7="" src="./NIO 看破也说破（五）Buffer_Java_InfoQ_files/f441b876.jpg" alt="用户头像" class="com-avatar" style="width: 40px; height: 40px;"><!----></div></div><div data-v-fcafb8d2="" class="reply-author"><span data-v-3bc80670="" data-v-6281d13f="" data-v-fcafb8d2="" class="ctn reply-user"><a data-v-3bc80670="" rel="nofollow" com-author-name="" class="com-author-name">AngkorW</a><!----></span><!----></div><div data-v-fcafb8d2="" class="reply-content"><span data-v-fcafb8d2="" class="">good</span><!----></div><div data-v-fcafb8d2="" class="reply-operation"><div data-v-fcafb8d2="" class="date">2020-09-14 13:04 <!----></div><div data-v-fcafb8d2="" class="reply-action"><span data-v-fcafb8d2="" class="like-btn"><i data-v-fcafb8d2="" class="iconfont"></i> 0 </span><span data-v-fcafb8d2="" class="reply-btn"><i data-v-fcafb8d2="" class="iconfont"></i><em data-v-fcafb8d2="">回复</em></span></div></div><!----></div><div data-v-fcafb8d2="" data-v-54bade26="" data-v-b7e0eae6="" class="reply-item comment-item"><div data-v-54bade26="" data-v-fcafb8d2="" class="comment-avatar"><div data-v-7b3025e7="" data-v-54bade26="" class="com-avatar-wrap" data-v-fcafb8d2=""><img data-v-7b3025e7="" src="" alt="用户头像" class="com-avatar" style="width: 40px; height: 40px;"><!----></div></div><div data-v-fcafb8d2="" class="reply-author"><span data-v-3bc80670="" data-v-6281d13f="" data-v-fcafb8d2="" class="ctn reply-user"><a data-v-3bc80670="" rel="nofollow" com-author-name="" class="com-author-name">zen</a><!----></span><!----></div><div data-v-fcafb8d2="" class="reply-content"><span data-v-fcafb8d2="" class="">真正的深入浅出！很精彩👏</span><!----></div><div data-v-fcafb8d2="" class="reply-operation"><div data-v-fcafb8d2="" class="date">2020-06-07 16:56 <!----></div><div data-v-fcafb8d2="" class="reply-action"><span data-v-fcafb8d2="" class="like-btn"><i data-v-fcafb8d2="" class="iconfont"></i> 0 </span><span data-v-fcafb8d2="" class="reply-btn"><i data-v-fcafb8d2="" class="iconfont"></i><em data-v-fcafb8d2="">回复</em></span></div></div><!----><div data-v-54bade26="" data-v-fcafb8d2="" class="reply-list"><span data-v-54bade26="" data-v-fcafb8d2=""><div data-v-fcafb8d2="" data-v-54bade26="" class="reply-item"><div data-v-fcafb8d2="" class="reply-author"><span data-v-3bc80670="" data-v-6281d13f="" data-v-fcafb8d2="" class="ctn reply-user"><a data-v-3bc80670="" rel="nofollow" com-author-name="" class="com-author-name">小眼睛聊技术</a><!----></span><!----></div><div data-v-fcafb8d2="" class="reply-content"><span data-v-fcafb8d2="" class="">谢谢肯定，欢迎转发，推荐，一起讨论</span><!----></div><div data-v-fcafb8d2="" class="reply-operation"><div data-v-fcafb8d2="" class="date">2020-06-07 19:04 <!----></div><div data-v-fcafb8d2="" class="reply-action"><span data-v-fcafb8d2="" class="like-btn"><i data-v-fcafb8d2="" class="iconfont"></i> 0 </span><span data-v-fcafb8d2="" class="reply-btn"><i data-v-fcafb8d2="" class="iconfont"></i><em data-v-fcafb8d2="">回复</em></span></div></div><!----></div></span><!----></div></div><div data-v-fcafb8d2="" data-v-54bade26="" data-v-b7e0eae6="" class="reply-item comment-item"><div data-v-54bade26="" data-v-fcafb8d2="" class="comment-avatar"><div data-v-7b3025e7="" data-v-54bade26="" class="com-avatar-wrap" data-v-fcafb8d2=""><img data-v-7b3025e7="" src="./NIO 看破也说破（五）Buffer_Java_InfoQ_files/4d780f27.jpg" alt="用户头像" class="com-avatar" style="width: 40px; height: 40px;"><!----></div></div><div data-v-fcafb8d2="" class="reply-author"><span data-v-3bc80670="" data-v-6281d13f="" data-v-fcafb8d2="" class="ctn reply-user"><a data-v-3bc80670="" rel="nofollow" com-author-name="" class="com-author-name">乐白</a><!----></span><!----></div><div data-v-fcafb8d2="" class="reply-content"><span data-v-fcafb8d2="" class="">感谢继续分享这个专题，InfoQ首页推荐。</span><!----></div><div data-v-fcafb8d2="" class="reply-operation"><div data-v-fcafb8d2="" class="date">2020-06-05 09:05 <!----></div><div data-v-fcafb8d2="" class="reply-action"><span data-v-fcafb8d2="" class="like-btn"><i data-v-fcafb8d2="" class="iconfont"></i> 0 </span><span data-v-fcafb8d2="" class="reply-btn"><i data-v-fcafb8d2="" class="iconfont"></i><em data-v-fcafb8d2="">回复</em></span></div></div><!----><div data-v-54bade26="" data-v-fcafb8d2="" class="reply-list"><span data-v-54bade26="" data-v-fcafb8d2=""><div data-v-fcafb8d2="" data-v-54bade26="" class="reply-item"><div data-v-fcafb8d2="" class="reply-author"><span data-v-3bc80670="" data-v-6281d13f="" data-v-fcafb8d2="" class="ctn reply-user"><a data-v-3bc80670="" rel="nofollow" com-author-name="" class="com-author-name">小眼睛聊技术</a><!----></span><!----></div><div data-v-fcafb8d2="" class="reply-content"><span data-v-fcafb8d2="" class="">🌹</span><!----></div><div data-v-fcafb8d2="" class="reply-operation"><div data-v-fcafb8d2="" class="date">2020-06-05 10:39 <!----></div><div data-v-fcafb8d2="" class="reply-action"><span data-v-fcafb8d2="" class="like-btn"><i data-v-fcafb8d2="" class="iconfont"></i> 0 </span><span data-v-fcafb8d2="" class="reply-btn"><i data-v-fcafb8d2="" class="iconfont"></i><em data-v-fcafb8d2="">回复</em></span></div></div><!----></div></span><!----></div></div><div data-v-4c7bd645="" data-v-b7e0eae6="" class="com-more-button loading-btn"><span data-v-4c7bd645="" class="finish-label">没有更多了</span></div></div></div></div><!----></div><!----><div data-v-4449d9fe="" data-v-4a1c10f0="" id="gk-layer" gkmodal-color="common" class="report-modal Modal_gk-modal_3ly5T" data-v-b110a92e=""><!----><!----></div><div data-v-355438c6="" data-v-4a1c10f0="" id="gk-layer" gkmodal-color="base" class="share-weixin-modal Modal_gk-modal_3ly5T" data-v-b110a92e=""><!----><!----></div><div data-v-4b5aad81="" data-v-4a1c10f0="" id="gk-layer" gkmodal-color="base" class="modal-share-horde Modal_gk-modal_3ly5T" data-v-b110a92e=""><!----><!----></div><!----></div><!----><div data-v-0dc6ee4d="" data-v-4a1c10f0="" class="nps-score" data-v-b110a92e=""><div data-v-0dc6ee4d="" id="gk-layer" gkmodal-color="common" class="nps-modal Modal_gk-modal_3ly5T"><!----><!----></div><div data-v-0dc6ee4d="" id="gk-layer" gkmodal-color="common" class="nps-modal-thank Modal_gk-modal_3ly5T"><!----><!----></div></div></div><div data-v-b110a92e="" id="check-bottom-bar"></div><div data-v-b110a92e="" layout-footer-wrap="" class="layout-footer-wrap"><div data-v-c5384832="" data-v-b110a92e="" class="footer layout-footer"><ul data-v-c5384832="" class="layout-content"><li data-v-c5384832="" class="theme"><div data-v-c5384832="" class="logo"><img data-v-c5384832="" src="./NIO 看破也说破（五）Buffer_Java_InfoQ_files/logo.3bdee6e4.png" alt="logo"><p data-v-c5384832="">促进软件开发及相关领域知识与创新的传播</p></div></li><li data-v-c5384832=""><dl data-v-c5384832="" class="footer-nav"><dt data-v-c5384832="">InfoQ</dt><dd data-v-c5384832=""><!----><a data-v-c5384832="" href="https://www.infoq.cn/about" target="_blank" rel="noopener nofollow">关于我们</a></dd><dd data-v-c5384832=""><!----><a data-v-c5384832="" href="https://www.infoq.cn/contribute" target="_blank" rel="noopener nofollow">我要投稿</a></dd><dd data-v-c5384832=""><!----><a data-v-c5384832="" href="https://www.geekbang.org/partner" target="_blank" rel="noopener nofollow">合作伙伴</a></dd><dd data-v-c5384832=""><!----><a data-v-c5384832="" href="https://www.lagou.com/gongsi/j43775.html" target="_blank" rel="noopener nofollow">加入我们</a></dd><dd data-v-c5384832=""><!----><a data-v-c5384832="" href="https://infoq.cn/official/account" target="_blank" rel="noopener nofollow">关注我们</a></dd></dl></li><li data-v-c5384832=""><dl data-v-c5384832="" class="footer-nav"><dt data-v-c5384832="">联系我们</dt><dd data-v-c5384832=""><!----><a data-v-c5384832="" href="mailto:editors@geekbang.com" target="_blank" rel="noopener nofollow">内容投稿：editors@geekbang.com</a></dd><dd data-v-c5384832=""><!----><a data-v-c5384832="" href="mailto:hezuo@geekbang.com" target="_blank" rel="noopener nofollow">业务合作：hezuo@geekbang.com</a></dd><dd data-v-c5384832=""><!----><a data-v-c5384832="" href="mailto:feedback@geekbang.com" target="_blank" rel="noopener nofollow">反馈投诉：feedback@geekbang.com</a></dd><dd data-v-c5384832=""><!----><a data-v-c5384832="" href="mailto:zhaopin@geekbang.com" target="_blank" rel="noopener nofollow">加入我们：zhaopin@geekbang.com</a></dd><dd data-v-c5384832=""><!----><span data-v-c5384832="">联系电话：010-64738142</span></dd><dd data-v-c5384832=""><!----><span data-v-c5384832="">地址：北京市朝阳区望京北路9号2幢7层A701</span></dd></dl></li><li data-v-c5384832=""><dl data-v-c5384832="" class="footer-nav"><dt data-v-c5384832="">InfoQ 近期会议</dt><dd data-v-c5384832=""><!----><a data-v-c5384832="" href="https://qcon.infoq.cn/2024/shanghai?utm_source=infoq&amp;utm_medium=footer" target="_blank" rel="noopener nofollow">上海 · QCon 全球软件开发大会 2024.10.18-19</a></dd><dd data-v-c5384832=""><!----><a data-v-c5384832="" href="https://aicon.infoq.cn/202412/beijing/?utm_source=infoq&amp;utm_medium=footer" target="_blank" rel="noopener nofollow">北京 · AICon 全球人工智能开发与应用大会 2024.12.13-14</a></dd></dl></li><li data-v-c5384832=""><dl data-v-c5384832="" class="footer-nav"><dt data-v-c5384832="">全球 InfoQ</dt><dd data-v-c5384832=""><img data-v-c5384832="" src="./NIO 看破也说破（五）Buffer_Java_InfoQ_files/55cd81623e36f5ab7a7db74d60b74838.png" alt="会议图片"><a data-v-c5384832="" href="https://www.infoq.com/" target="_blank" rel="noopener nofollow">InfoQ  En</a></dd><dd data-v-c5384832=""><img data-v-c5384832="" src="./NIO 看破也说破（五）Buffer_Java_InfoQ_files/95fe851c02c86120e9037eada6a36d13.png" alt="会议图片"><a data-v-c5384832="" href="https://www.infoq.com/jp/" target="_blank" rel="noopener nofollow">InfoQ Jp</a></dd><dd data-v-c5384832=""><img data-v-c5384832="" src="./NIO 看破也说破（五）Buffer_Java_InfoQ_files/2aa440b6d94e94f64c508f16da38933e.png" alt="会议图片"><a data-v-c5384832="" href="http://www.infoq.com/fr/" target="_blank" rel="noopener nofollow">InfoQ Fr</a></dd><dd data-v-c5384832=""><img data-v-c5384832="" src="./NIO 看破也说破（五）Buffer_Java_InfoQ_files/4e737ce82bc7c8a1c2f2307bcea9a11e.png" alt="会议图片"><a data-v-c5384832="" href="http://www.infoq.com/br/" target="_blank" rel="noopener nofollow">InfoQ Br</a></dd></dl></li></ul><div data-v-c5384832="" class="copyright"> Copyright © 2024, Geekbang Technology Ltd. All rights reserved. 极客邦控股（北京）有限公司 | <a data-v-c5384832="" target="_blank" href="https://beian.miit.gov.cn/" class="icp"> 京 ICP 备 16027448 号 - 5</a><a data-v-c5384832="" target="_blank" href="http://www.beian.gov.cn/portal/registerSystemInfo?recordcode=11010502039052"><img data-v-c5384832="" src="./NIO 看破也说破（五）Buffer_Java_InfoQ_files/beian.d0289dc0.png" alt="京公网安备"><span data-v-c5384832="">京公网安备 11010502039052号</span></a><a data-v-c5384832="" target="_blank" href="https://time.geekbang.org/hybrid/certificates" class="icp"> | 产品资质</a></div></div></div><div data-v-b110a92e="" id="gk-layer" gkmodal-color="common" class="offline-modal Modal_gk-modal_3ly5T"><!----><!----></div></div>
<img src="./NIO 看破也说破（五）Buffer_Java_InfoQ_files/logo-121-75.yuij86g.png" alt="NIO 看破也说破（五）： 搞，今天就搞，搞懂Buffer_Java_小眼睛聊技术_InfoQ写作社区" style="display: none;">
<script>
    (function (i, s, o, g, r, a, m) {
        i['GoogleAnalyticsObject'] = r; i[r] = i[r] || function () {
            (i[r].q = i[r].q || []).push(arguments)
        }, i[r].l = 1 * new Date(); a = s.createElement(o),
            m = s.getElementsByTagName(o)[0]; a.async = 1; a.src = g; m.parentNode.insertBefore(a, m)
    })(window, document, 'script', 'https://www.google-analytics.com/analytics.js', 'ga');
    ga('create', 'UA-103082599-11', 'auto');
    ga('send', 'pageview');
</script>
<script>
    var isRobot = /ltdgeekbang/i.test(window.navigator.userAgent.toLowerCase())
    if (!isRobot) {
        var __gBaiduSiteIdConfig__ = {
            infoq: '094d2af1d9a57fd9249b3fa259428445',
            xie: 'c53c258392315152cda6662d99774537'
        };
        var _hmt = _hmt || [];
        _hmt.push(['_setAccount', __gBaiduSiteIdConfig__.infoq]);
        _hmt.push(['_setAutoPageview', true]);
        _hmt.push(['_setAccount', __gBaiduSiteIdConfig__.xie]);
        _hmt.push(['_setAutoPageview', true]);

        (function() {
            var hm = document.createElement("script");
            hm.src = "https://hm.baidu.com/hm.js?" + __gBaiduSiteIdConfig__.infoq;
            var s = document.getElementsByTagName("script")[0];
            s.parentNode.insertBefore(hm, s);
        })();
        
        (function() {
            var hm = document.createElement("script");
            hm.src = "https://hm.baidu.com/hm.js?" + __gBaiduSiteIdConfig__.xie;
            var s = document.getElementsByTagName("script")[0];
            s.parentNode.insertBefore(hm, s);
        })();
        
    }
</script>
<script>
    
    var isSmart = /swan\//.test(window.navigator.userAgent) || /^webswan-/.test(window.name);
    if (isSmart) {
        var smart = document.createElement("script");
        smart.src = "https://b.bdstatic.com/searchbox/icms/searchbox/js/swan-2.0.21.js";
        var s = document.getElementsByTagName("script")[0];
        s.parentNode.insertBefore(smart, s);
    }
</script>
<script>
    (function(para) {
        var p = para.sdk_url, n = para.name, w = window, d = document, s = 'script',x = null,y = null;
        if(typeof(w['sensorsDataAnalytic201505']) !== 'undefined') {
            return false;
        }
        w['sensorsDataAnalytic201505'] = n;
        w[n] = w[n] || function(a) {return function() {(w[n]._q = w[n]._q || []).push([a, arguments]);}};
        var ifs = ['track','quick','register','registerPage','registerOnce','trackSignup', 'trackAbtest', 'setProfile','setOnceProfile','appendProfile', 'incrementProfile', 'deleteProfile', 'unsetProfile', 'identify','login','logout','trackLink','clearAllRegister','getAppStatus'];
        for (var i = 0; i < ifs.length; i++) {
            w[n][ifs[i]] = w[n].call(null, ifs[i]);
        }
        if (!w[n]._t) {
            x = d.createElement(s), y = d.getElementsByTagName(s)[0];
            x.async = 1;
            x.src = p;
            x.setAttribute('charset','UTF-8');
            w[n].para = para;
            y.parentNode.insertBefore(x, y);
        }
    })({
        sdk_url: 'https://static.sensorsdata.cn/sdk/1.15.15/sensorsdata.min.js',
        heatmap_url: 'https://static.sensorsdata.cn/sdk/1.15.15/heatmap.min.js',
        name: 'sensors',
        server_url: 'https://sscentry.geekbang.org/sa?project=production',
        show_log: false,
        is_track_single_page: true,
        heatmap: {
            clickmap: 'not_collect',
            scroll_notice_map: 'not_collect'
        },
        preset_properties: {
            latest_referrer_host: true,
            latest_landing_page: true,
            url: true
        }
    });
</script>
<script>
    (function(win, export_obj) {
        win['LogAnalyticsObject'] = export_obj;
        if (!win[export_obj]) {
            function _collect() {
                _collect.q.push(arguments);
            }
            _collect.q = _collect.q || [];
            win[export_obj] = _collect;
        }
        win[export_obj].l = +new Date();
    })(window, 'collectEvent');
</script>
<script async="" src="./NIO 看破也说破（五）Buffer_Java_InfoQ_files/collect-rangers-v5.1.4.js.下载"></script>

    <script type="text/javascript" src="./NIO 看破也说破（五）Buffer_Java_InfoQ_files/main.js.下载"></script>



<div id="mantisImgViewBg" style="display: none">
			<div id="mantisImgView_header">
				<img src="./NIO 看破也说破（五）Buffer_Java_InfoQ_files/rotateIcon.png" alt="" id="leftTurn">
				<img src="./NIO 看破也说破（五）Buffer_Java_InfoQ_files/rotateIcon.png" alt="" id="rightTurn">
				<img src="./NIO 看破也说破（五）Buffer_Java_InfoQ_files/blowUpIcon.png" alt="" id="blowUp">
				<img src="./NIO 看破也说破（五）Buffer_Java_InfoQ_files/minificationIcon.png" alt="" id="minification">
			</div>
			<div id="imgBox">
				<img id="viewImg" src="https://xie.infoq.cn/article/9e57819677d77f9a34852f6e9" alt="">
			</div>
		</div><iframe id="MANTIS-CHAT-DIV" frameborder="no" style="z-index: 2147483646; position: fixed; width: 0; height: 0;box-shadow: 0 2px 25px 0 rgba(0,0,0,.3);" src="./NIO 看破也说破（五）Buffer_Java_InfoQ_files/saved_resource.html"></iframe><div data-v-742c2edc="" id="gkui-message-list" style="top: 24px;"><span data-v-742c2edc=""></span></div><div id="gkui-modal-controller"><!----></div><div class="common-login-modal"><div data-v-66e08e49="" id="gk-layer" gkmodal-color="base" class="modal-login Modal_gk-modal_3ly5T"><!----><!----></div><div data-v-95b8db28="" id="gk-layer" gkmodal-color="base" class="modal-guide Modal_gk-modal_3ly5T"><!----><!----></div><div data-v-0b61e37e="" id="gk-layer" gkmodal-color="base" class="modal-receive-success Modal_gk-modal_3ly5T"><!----><!----></div><div data-v-de1e5142="" id="gk-layer" gkmodal-color="base" class="modal-rebind Modal_gk-modal_3ly5T"><!----><!----></div></div><div tabindex="-1" role="dialog" aria-hidden="true" class="pswp pswp--zoom-allowed"><div class="pswp__bg"></div><div class="pswp__scroll-wrap"><div class="pswp__container"><div class="pswp__item"></div><div class="pswp__item"></div><div class="pswp__item"></div></div><div class="pswp__ui pswp__ui--hidden"><div class="pswp__top-bar"><div class="pswp__counter"></div><button title="Close (Esc)" class="pswp__button pswp__button--close"></button><button title="Share" class="pswp__button pswp__button--share"></button><button title="Toggle fullscreen" class="pswp__button pswp__button--fs"></button><button title="Zoom in/out" class="pswp__button pswp__button--zoom"></button><div class="pswp__preloader"><div class="pswp__preloader__icn"><div class="pswp__preloader__cut"><div class="pswp__preloader__donut"></div></div></div></div></div><div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap"><div class="pswp__share-tooltip"></div></div><button title="Previous (arrow left)" class="pswp__button pswp__button--arrow--left"></button><button title="Next (arrow right)" class="pswp__button pswp__button--arrow--right"></button><div class="pswp__caption"><div class="pswp__caption__center"></div></div></div></div></div><div><div id="gk-layer" gkmodal-color="logPhone" class="Modal_gk-modal_90vUO"><!----><!----></div></div><link type="text/css" rel="stylesheet" href="./NIO 看破也说破（五）Buffer_Java_InfoQ_files/PCMiniStyle.css"><div id="pcMsgTip" style="display:none;"><div class="pcMsgTipBox"><img id="pcMsgTipGB" src="./NIO 看破也说破（五）Buffer_Java_InfoQ_files/close(1).png" alt="" onclick="mantisOnClosePCMsgList()"><div id="pcMsgTipMsgList" onclick="mantis.requestChat()"></div></div><span class="pcMsgTipAfter"> </span></div><div id="MANTIS_INV_INNER_DIV" class="mantisPcInvite_center" style="display:none;left: 50%;transform: translate(-50%,-50%);"><img src="./NIO 看破也说破（五）Buffer_Java_InfoQ_files/closeInviteIcon.png" class="closeInviteIcon" onclick="mantisHideInvite()"><img style="width:380px" src="./NIO 看破也说破（五）Buffer_Java_InfoQ_files/pcInvite.png" onclick="mantis.requestChat()"></div><div><template shadowrootmode="closed"><link rel="stylesheet" href="chrome-extension://ghgabhipcejejjmhhchfonmamedcbeod/fcss41/ebtn41.css"><svg width="16px" height="16px" hide=""><path id="__path" d="M16 14V2a2 2 0 00-2-2H2a2 2 0 00-2 2v12c0 1.1.9 2 2 2h12a2 2 0 002-2z"></path><path fill="#f9f6e8" d="M12.9 12.2c.2-.2.3-.5.3-.8 0-.6-.5-1.2-1.2-1.2-.3 0-.6.1-.9.4-.7.7-1.7 1-2.6 1-2 0-3.8-1.6-3.8-3.6s1.7-3.6 3.8-3.6c1 0 2 .3 2.6 1 .3.3.6.4.9.4.7 0 1.3-.5 1.3-1.2 0-.3-.2-.6-.4-.8A6.4 6.4 0 008.5 2a6.1 6.1 0 00-6.3 6c0 3.3 2.8 6 6.3 6 1.6 0 3.2-.6 4.4-1.8z"></path></svg></template></div><!----><!----><!----><!----><!----><!----><!----><img src="" id="page-complete" style="display: none;"></body></html>